Why is jest running my Typescript test twice and always failing once?

Viewed 990

I am writing a test in my backend to test a simple route of my API. I am using Typescript and Jest to write the test and it is all happening inside of a docker container which I start by using docker-compose.

I have a helper class for my tests, which creates an instance of a express webserver and a database connection via the init function. In the shutdown function it closes the connection etc. So my test looks like this:

import { Helper } from "./helper";
import request from 'supertest'

describe('article', () => {
    const helper = new Helper();
    beforeAll(async () => {
        await helper.init();
    });

    afterAll(async () => {
        await helper.shutdown();
    });

    it('should test if reaching the api is possible', async (done) => {
        request(helper.app)
        .get('/test')
        .send()
        .set('Accept', 'application/json')
        .expect(200)
        .end( (error, response) => {
            if(error) throw error;
            expect(response.body.message).toBe("Hello");
        });
    });

To execute the test, I use this script "test": "jest --verbose --forceExit --runInBand --detectOpenHandles"

If I execute the test like this, I get the following output:

testOutput

I changed the Timeout as proposed, but it didnt make a difference. Now for testing purposes I made my route return "Helloo" instead of the expected "Hello". This is the output that I recieve:

newTestOutput

So it obviously gets a response. My Question is, why is it running the test twice and why does it always timeout at the second test?

This is my jest.config.js

module.exports = {
    "roots": [
      "<rootDir>/src"
    ],
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
    "moduleFileExtensions": [
      "ts",
      "js"
    ],
  }
2 Answers

When using async tests you could call the done callback from the body of your async handler.

something like this should do it:

it('should test if reaching the api is possible', (done) => { // << async tests have the done callback declared here
        request(helper.app)
        .get('/test')
        .send()
        .set('Accept', 'application/json')
        .expect(200)
        .end( (error, response) => {
            if(error) {
              done(error);
            } else {
              expect(response.body.message).toBe("Hello");
              done();
            }
        });
    });

Solution

Since this question is getting some attention recently, I removed the solution from the question text and added it to this answer. I am not sure if this is/was the right approach and if I did something redundant, since I used jest for the second time and have not touched it ever since. But at the time I posted the question, this solved my problem:

I had to surround the expectations with a try-catch block, dont mark the test as async but pass done function in and call the done function after the expectations and in the catch block aswell.

Related