我想测试一个调用firebase.auth().sendPasswordResetEmail()
click的组件,所以我想测试 firebase 被调用 onClick,但我不确定如何实现 - 我不想在测试中调用 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)
})
但我收到错误:
预期模拟函数已被调用一次,但被调用了零次。
有谁知道我做错了什么?
多谢