I’m trying to test a nodejs function using Jest. I’m a complete beginner in Jest, so I assume this is a problem in the way I have structured my tests.
When called manually or from within the application, the function works fine. But when called from a Jest test, it either times out, returns an empty object or otherwise falls over.
The function to be tested:
async function createUser(username, password){
try{
const user = await UserModel.create({ username, password });
return true;
} catch(error){
if(error.code == 11000){
const field = Object.keys(error.keyValue);
const err = Error("Account with username " + field + " already exists");
throw err;
}
if(error.name == 'ValidationError'){
const err = Error("Error creating new user");
throw err;
}
const err = Error("Unknown error creating new user");
throw err;
}
}
and the Jest tests I have created:
test('createUser: Non empty input should create account and return true', async () => {
const data = await register.createUser('johnsmith1', 'smithjohn');
expect(data).toBe(true);
});
test('createUser: Duplicate user/pass should not create user and should throw error', async () => {
try{
await register.createUser('johnsmith1', 'smithjohn');
} catch(error){
expect(error).toMatch('error');
}
});
When run both tests timeout:
createUser: Duplicate user/pass should not create user and should throw error
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
74 | });
75 |
> 76 | test('createUser: Duplicate user/pass should not create user and should throw error', async () => {
| ^
77 | try{
78 | await register.createUser('johnsmith1', 'smithjohn');
79 | } catch(error){
at Object.test (tests/register.test.js:76:1)
2
Answers
Thanks to Marek Rozmus.
The solution was that I needed to use mocks to return dummy data instead of using a call to mongoose.
After mocking the calls, the tests worked as expected. Also learned about formulating better tests - we're not testing mongoose, only whether our code can handle what mongoose might return (success, error, timeout etc.)
Your
createUser
takes more than 5 seconds, which is the default timeout in jest.In order to increase the timeout only for a single test, as a third param to the test function.
More info here: jset setTimeout per test
In order to increase the timeout globally, you can read this
configure-jest-timeout-once-for-all-tests