Asynchronous Code Test in JEST

Bibek Magar
wesionaryTEAM
Published in
3 min readJun 23, 2020

--

Asynchronous code is a fundamental concept of web today. We found a lot of asynchronous code in JavaScript. Though, JavaScript is single threaded, there are different ways for executing of asynchronous code for fast and efficient programs. Some people might think asynchronous test are the harder to write test. To avoid all the confusion let’s get ahead with an example.

This is the example of the asynchronous that we are gonna test.

const fetch = require("node-fetch");const getEmployees = async (fetch) => {
const getRequest = await fetch(
"http://dummy.restapiexample.com/api/v1/employees"
);
const data = await getRequest.json();
console.log(data);
return {
status: data.status,
employees: data.data,
};
};
module.exports = { getEmployees };

In above code there is simply a asynchronous code that fetch employee data and return as an object.

Now we are gonna write a test for this file.

const fetch = require("node-fetch");
const api = require("./script");
it("call api to get employees", () => {
api.getEmployees(fetch).then((data) => {
expect(data.status).toEqual("success");
});
});

After running :

npm run test

We can see that test looks working.

In testing we always want to make sure that we fail our tests and check that the tests are actually checking, what we are intended to test.

We can use expect.assertions to check our intention of test. Assertions are these things:
expect(data.status).toEqual(“success”);

Since in our code we only expect for one things, so we can conclude that we have one assertions. So, the code will be:

const fetch = require("node-fetch");
const api = require("./script");
it("call api to get employees", () => {
expect.assertions(1);
api.getEmployees(fetch).then((data) => {
expect(data.status).toEqual("success");
});
});

And this is the good way to test that our intended test (expect(“success”)) is actually running, especially in asynchronous code.
Lets run test and see what happens.

After adding assertion, we run the test.

As we can see the test fails, there is expected to be one assertion to be called but received zero assertion calls. This is all because of asynchronous test.
The problem is that the test are actually completing as soon as getEmployees() get called. And, promise returned a pending state so promise is gonna return before we received data.

There are different ways to solve this.

First way is to use single argument called “done”.

const fetch = require("node-fetch");
const api = require("./script");
it("call api to get employees", (done) => {
expect.assertions(1);
api.getEmployees(fetch).then((data) => {
expect(data.status).toEqual("success");
done();
});
});

Instead of empty argument, we can have done as an argument in our test which is automatically passed to a test. “Done” helps to wait until done callback is called before the test is finished. And usually, put after expect statement.

Second way of handling asynchronous is return the “promise”.

it("call api to get employees", () => {
expect.assertions(1);
return api.getEmployees(fetch).then((data) => {
expect(data.status).toEqual("success");
});
});

Because we are returning the asynchronous call, it waits until our promise returns. And, if promise get rejected the test will automatically gets fail.
After running test, we can see that

After adding return or done statement we can see test get passed.

Summary:
So, when running asynchronous test always use expect assertions. Always, make sure that your assertions are being tested.
And, also make sure you use done callback or return the promise.

Thank you for reading :)

Link to a repo:
https://github.com/beevekmgr/Asynchronous-Testing-Example
Follow me: @beevekmgrz

--

--