我想测试点击时调用firebase.auth().sendPasswordResetEmail()
的组件,所以我想测试firebase是否被称为onClick,但不确定如何实现-我不想在api中调用api测试。
我希望获得有关模拟/拦截Firebase调用的一般指导。
我正在将React与Jest和React测试库一起使用。
这是有问题的组件
import React from 'react'
import { withFirebase } from '../Firebase'
interface PFProps {
firebase: firebase.app.App
}
interface S {
email: string
}
interface Error {
message?: string
}
const PasswordForget = ({ firebase }: PFProps) => {
const initialState = { email: '' }
const stateReducer = (state: S, update: { [x: string]: string }) => ({
...state,
...update,
})
const [state, dispatch] = React.useReducer(stateReducer, initialState)
const [error, setError] = React.useState<Error>()
const isValid = () => validator.isEmail(state.email)
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault()
if (!isValid()) {
return setError({ message: messages.emailIsInvalid })
}
firebase
.auth()
.sendPasswordResetEmail(state.email)
.then(success => console.log(success))
.catch(error => setError(error))
dispatch(initialState)
}
const handleChange = ({
currentTarget: { name, value },
}: React.ChangeEvent<HTMLInputElement>) => {
setError(undefined)
dispatch({ [name]: value })
}
return (
<>
<form onSubmit={handleSubmit} data-testid="form" noValidate>
{error && error.message && <FormErrorPanel message={error.message} />}
<Input
type="email"
name="email"
data-testid="pwf-email"
value={state.email}
onChange={handleChange}
placeholder="Enter your email address"
/>
<Button>Reset password</Button>
</form>
</>
)
}
const PasswordForgetLink = () => (
<p>
<Link to={ROUTES.PASSWORD_FORGET}>Forgotten password</Link>
</p>
)
export { PasswordForgetLink }
export default withFirebase(PasswordForget)
这是我目前尝试模拟Firebase的方式:
import React from 'react'
import '@testing-library/jest-dom/extend-expect'
import { render, cleanup, fireEvent } from '@testing-library/react'
import { FirebaseContext } from '../../Firebase'
import firebase from '../../Firebase'
import PasswordForget from '../index'
jest.mock('../../Firebase/firebase', () => {
return {
auth: jest.fn(() => ({
sendPasswordResetEmail: jest.fn(() => Promise.resolve()),
})),
}
})
afterEach(cleanup)
const setup = () => {
const utils = render(
<FirebaseContext.Provider value={firebase}>
<PasswordForget />
</FirebaseContext.Provider>,
)
const form = utils.getByTestId('form')
const emailInput = utils.getByTestId('pwf-email') as HTMLInputElement
const h1 = utils.getByText(/Forgotten Password/i)
return {
h1,
form,
emailInput,
...utils,
}
}
test('should call sendPasswordResetEmail method when the form is submitted with a valid email', () => {
const { form, emailInput } = setup()
const email = 'peterparker@foo.com'
fireEvent.change(emailInput, { target: { value: email } })
expect(emailInput.value).not.toBeNull()
fireEvent.submit(form)
expect(firebase.auth().sendPasswordResetEmail).toHaveBeenCalledTimes(1)
})
但是我得到了错误:
预期模拟函数被调用了一次,但被调用了零次。
有人知道我在做什么错吗?
很多thaks
答案 0 :(得分:0)
如果您使用的是create-react-app,则可以尝试在“ src”文件夹中添加“ 模拟”文件夹,然后在“ 内部添加“ firebase.js” >模仿”文件夹
在“ firebase.js”中:
const mockFirebase = {
auth: jest.fn(() => mockFirebase ),
sendPasswordResetEmail: jest.fn(() => Promise.resolve(fakeResponse))
};
export { mockFirebase as default };
“ fakeResponse”是您的预期响应。
然后在您的test.js中删除它们:
jest.mock('../../Firebase/firebase', () => {
return {
auth: jest.fn(() => ({
sendPasswordResetEmail: jest.fn(() => Promise.resolve()),
})),
}
})
查看Jest官方网站以获取更多信息:https://jestjs.io/docs/en/manual-mocks