I want to test a React component with Jest and Enzyme. This component is a login form and when the user clicks on the login button, I want to check that depending the result, the object model is well updated accordingly.
Here is the part of the code that is called when the user clicks on on the submit button.
// Login.jsx
handleSubmit(e) {
var that = this;
this.setState({stateResult: "", errorLabel: ""});
if(e) {
e.preventDefault();
e.stopPropagation();
}
MyService.login(this.state.email, this.state.password).then(function(account) {
that.setState({stateResult: "login-ok", errorLabel: ""});
}).catch(function(err) {
that.setState({stateResult: "login-error", errorLabel: err.data.message});
});
};
I wrote a Jest test. Here is the code:
// Login-test.js
test('that when the signin fails, the stateResult model is updated with login-error', () => {
const wrapper = shallow(<Landing />);
wrapper.find('a#landingjsx-signin').simulate('click');
wrapper.update();
setTimeout(function() {
expect(wrapper.state().stateResult).toEqual("login-error");
}, 100);
});
For testing it, I use a mock of MyService
jest.mock('../../../modules/MyService.js');
Here is the code of my mock:
//MyService.js
class MyService {
constructor() {
}
login(user, password) {
return new Promise((resolve, reject) => {
process.nextTick(() => {
if(user === "aaa") {
resolve({});
}
else {
reject({
data: {
message: "bad-password"
}
});
}
});
});
}
}
export default new MyService();
The test fails right :-)
My question is: How to remove the setTimeout() call from my test ? Is there a better way to test this promise based function.
My problem is how to wait for the promise function to fail before expecting the result ?
Thanks in advance
Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail.
Try-catch with async/await (bad) It looks like using try-catch with async/await is the easiest way to achieve this as the rejected value is thrown: it("rejects (bad)", async () => { try { await promiseMe("Error"); } catch (e) { expect(e). toEqual("Error"); } }); But wait.
In order to mock asynchronous code in Jest, more specifically Promises, you can use the mockResolvedValue function. This will mock the return value of the Promise to be 42. In order to test a Promise in Jest, you need to turn your it block into async in order to use the await keyword in front of an expect statement.
The Jest library provides the jest. fn() function for creating a “mock” function. An optional implementation function may be passed to jest. fn() to define the mock function's behavior and return value. The mock function's behavior may be further specified using various methods provided to the mock function such as .
Just a hunch: try adding the done
callback.
// Login-test.js
test('that when the signin fails, the stateResult model is updated with login-error', (done) => {
const wrapper = shallow(<Landing />);
wrapper.find('a#landingjsx-signin').simulate('click');
wrapper.update();
setTimeout(function() {
try {
expect(wrapper.state().stateResult).toEqual("login-error");
done()
} catch (e) {
done.fail(e)
}
}, 100);
});
You need to wrap the expectation in try-catch, because expect throws on error and a test failure will cause done
not to be called.
Also see the jest docs for more extended examples.
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