I want to test my react login component, but the mock function have not been called:
Login:
export default class LoginPage extends PureComponent {
static propTypes = {
login: PropTypes.func.isRequired,
history: PropTypes.shape({
replace: PropTypes.func.isRequired,
}).isRequired,
};
onSubmit = (e) => {
this.props.login(this.state.username, this.state.password)
.then(() => {
this.props.history.replace('/');
});
};
render() {
return (
<form onSubmit={this.onSubmit}>
...
</form>
);
}
}
I use jest
+ enzyme
to test this:
const props = {
login: jest.fn(() => Promise.resolve('success')),
history: {
replace: jest.fn()
},
};
const wrapper = mount(<LoginPage {...props}/>);
const form = wrapper.find(Form);
const inputs = form.find('input');
const username = inputs.at(0);
const password = inputs.at(1);
username.simulate('change', {target: {value: 'Changed'}});
password.simulate('change', {target: {value: 'Changed'}});
form.simulate('submit');
expect(props.login).toBeDefined();
expect(props.history.replace).toBeDefined();
// this is success
expect(props.login).toBeCalled();
// this is failure
expect(props.history.replace).toBeCalled();
I mock two function, and the history.replace
should be called by login
, the login
mocked as Promise function.
expect(props.login).toBeCalled()
test success.
but expect(props.history.replace).toBeCalled()
test failure.
I log props.history.replace.mock
, it output { calls: [], instances: [] }
.
You need to inform Jest about the promise you are using otherwise it will not wait for so the test is over before the promise resolves. Here are the docs for testing async stuff.
Your test needs to become an async
function. The promise needs to be stored in a variable that can be used with await
after the form submit was fired:
it('does something', async () => {
const promise = Promise.resolve('success')
const props = {
login: jest.fn(() => promise),
history: {
replace: jest.fn()
},
};
const wrapper = mount(<LoginPage {...props}/>);
const form = wrapper.find(Form);
const inputs = form.find('input');
const username = inputs.at(0);
const password = inputs.at(1);
username.simulate('change', {target: {value: 'Changed'}});
password.simulate('change', {target: {value: 'Changed'}});
form.simulate('submit');
await promise;
expect(props.login).toBeDefined();
expect(props.history.replace).toBeDefined();
// this is success
expect(props.login).toBeCalled();
// this is failure
expect(props.history.replace).toBeCalled();
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With