我在组件上使用了依赖注入方法,这意味着我可以在没有所有样板的情况下模拟和测试方法。
例如,我有一个处理邀请的表单组件,如下所示:
import React, { useEffect } from 'react';
import { Formik } from 'formik';
import { validations } from '../../helpers';
import { checkIfTeamExists } from '../helpers';
const Invite = ({ send, userEmail, handleTeamCreation, auth, db, dbWhere }) => {
useEffect(() => {
checkIfTeamExists(send, dbWhere);
}, []);
return (
<Formik
initialValues={{ email: '' }}
onSubmit={values =>
handleTeamCreation(userEmail, values.email, db, auth, send)
}
validate={validations}
render={props => (
<form onSubmit={props.handleSubmit} data-testid="form">
<input
type="email"
placeholder="Please enter your email."
onChange={props.handleChange}
onBlur={props.handleBlur}
value={props.values.email}
name="email"
/>
{props.errors.email && (
<p className="red" data-testid="error">
{props.errors.email}
</p>
)}
<button type="submit">Submit</button>
</form>
)}
/>
);
};
export default Invite;
checkIfTeamExists 方法依赖于 firebase 身份验证,handleTeamCreation 方法写入 firestore。
当我在其父组件中引用该组件时,我像这样实例化它:
<Invite
send={send}
userEmail={value.user.user.email}
handleTeamCreation={handleTeamCreation}
auth={auth.sendSignInLinkToEmail}
db={db.collection('games')}
dbWhere={db.collection('games')
.where('player1', '==', value.user.user.email)
.get}
/>
然后,使用react-testing-library,在我的测试中,我能够用一个简单的jest.fn() 模拟出事情。
test('Invite form fires the send function on Submit ', async () => {
const handleTeamCreation = jest.fn();
const send = jest.fn();
const userEmail = 'ex@mple.com';
const db = jest.fn();
const auth = jest.fn();
const dbWhere = jest.fn().mockResolvedValue([]);
const { getByPlaceholderText, getByTestId } = render(
<Invite
send={send}
userEmail={userEmail}
handleTeamCreation={handleTeamCreation}
auth={auth}
db={db}
dbWhere={dbWhere}
/>
);
const inputNode = getByPlaceholderText('Please enter your email.');
const email = 'me@gmail.com';
fireEvent.change(inputNode, { target: { value: email } });
const formNode = getByTestId('form');
fireEvent.submit(formNode);
await wait(() => {
expect(handleTeamCreation).toHaveBeenCalledWith(
userEmail,
email,
db,
auth,
send
);
expect(handleTeamCreation).toHaveBeenCalledTimes(1);
});
});
并以同样的方式模拟了firestore where查询。
test('Invite form must contain a valid email address', async () => {
const send = jest.fn();
const db = jest.fn();
const dbWhere = jest.fn().mockResolvedValue([]);
const { getByPlaceholderText, queryByTestId } = render(
<Invite send={send} db={db} dbWhere={dbWhere} />
);
expect(queryByTestId('error')).not.toBeInTheDocument();
const inputNode = getByPlaceholderText('Please enter your email.');
const email = 'x';
fireEvent.change(inputNode, { target: { value: email } });
await wait(() => {
expect(queryByTestId('error')).toHaveTextContent('Invalid email address');
});
});
这很简单,但是很有效。它也很冗长,但我认为一个真实的用例会比一个人为的例子更有帮助。我希望这对某人有所帮助。