Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JEST with Express does not finish

I started to write tests with Jest of (nano)express application. The test starts the server at beforeAll() and closes it at afterAll(). I can see that the code is executed, but the JEST process does not end.

test.js

test('end to end test', async () => {
    const polls = await axios.get(`http://localhost:3000/bff/polls/last`);
    console.log(polls.data);
    expect(polls.data).toBeDefined();
});

beforeAll(() => {
    app.listen(3000, '0.0.0.0')
        .then(r => logger.info("Server started"));
});

afterAll(() => {
    if (app.close())
        logger.info("Server stopped");
});

Output from npm run test

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        5.625s
Ran all test suites.
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

When I run with jest --config jest.config.js --detectOpenHandles the test does not finish as well but there is no error and I need to kill it anyway.

The complete source code is there: https://github.com/literakl/mezinamiridici/blob/master/infrastructure/test/api.int.test.js

I have tested separatelly outside of the tests that nanoexpress will terminate the process with app.close() call. So it is JEST related.

Update: the same behaviour with promises

test('end to end test', () => {
    const polls = axios.get(`http://localhost:3000/bff/polls/last`);
    return expect(polls).resolves.toBeDefined();
});

Update:

Here you can find minimum reproducible repository: https://github.com/literakl/nano-options.git

I have switched from Axios to GotJS and the trouble is still there. When I run the test with npm run test from command line now, it fails with:

Timeout - Async callback was not invoked within the 20000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 20000ms timeout specified by jest.setTimeout.Error

When I start the test from WebStorm there is no error but the process keeps running.

like image 383
Leos Literak Avatar asked Oct 26 '25 08:10

Leos Literak


2 Answers

The root cause was an open handle of mongodb client. How did I find it?

1) install leakes-handle library

npm install leaked-handles --save-dev

2) import it to your test

require("leaked-handles");

3) the output

tcp handle leaked at one of:
    at makeConnection (infrastructure\node_modules\mongodb\lib\core\connection\connect.js:274:20)
tcp stream {
  fd: -1,
  readable: true,
  writable: true,
  address: { address: '127.0.0.1', family: 'IPv4', port: 54963 },
  serverAddr: null
}

If you cannot find the root cause, you can kill the JEST explicitelly with

jest --config jest.config.js --runInBand --forceExit
like image 66
Leos Literak Avatar answered Oct 28 '25 22:10

Leos Literak


UPDATE

My initial thought was that this is a winston related issue but it appears that jest testEnvironment has to be set to node in order for Axios to run propertly using the axios/lib/adapters/http adapter. You can check a related issue here "detect jest and use http adapter instead of XMLhttpRequest".

  1. Set testEnvironment: 'node' inside jest.config.js.
  2. Update create user test to run the done callback function at the end:
describe("user accounts", () => {
    test('create user', async (done) => {
        // let response = await axios.get(`${API}/users/1234`);
        let response = await axios.get(`${API}/users/1234`, getAuthHeader()); // TODO error with Authorization header

        expect(response.data.success).toBeTruthy();
        expect(response.data.data).toBeDefined();
        let profile = response.data.data;
        expect(profile.bio.nickname).toMatch("leos");
        expect(profile.auth.email).toMatch("[email protected]");

        // Call done here to let Jest know we re done with the async test call
        done();
    });
});
like image 22
Christos Lytras Avatar answered Oct 28 '25 22:10

Christos Lytras



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!