Sinane
Sinane

Reputation: 2010

supertest changing url at every test

I'm new to backend development and i face a problem that i don't understand.

I set up the 1st route of my API called "health" who just return a simple message to know if my server is up.

This route looks to works as expected.

However,

when I try to test this route with the method "toMatchSnapshot" from jest API, the test is not passing because of the in the url is changing constantly.

My test file "index.test.ts":

const request = supertest.agent(app);
describe("app", () => {

  it("should return a successful response for GET /health", async () => {
    const res = await request.get("/health");
    res.header = omit(res.header, ["date"]);
    expect(res).toMatchSnapshot();
  });

});

index of the server "index.ts":

const app = express();

expressService(app);

if (require.main === module) {
  app.listen(PORT, () => {
    console.log("server started at http://localhost:" + PORT);
  });
}

export default app;

my function "expressService":

const expressService = (app: Application) => {
    app.use(cors());
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json());

    app.use(api);
};

export default expressService;

My PORT variable: PORT = 3000;

-     "url": "http://127.0.0.1:49694/health",
+     "url": "http://127.0.0.1:52568/health",

this is where the test is failing.

Thank you for your answers.

Upvotes: 3

Views: 7627

Answers (2)

Maksim Kostromin
Maksim Kostromin

Reputation: 3798

Simple enough solution:

const request = require('supertest'); // npm i -ED supertest
const app = require('../app'); // your expressjs app
const { url } = request(app).get('/'); // next, just use url
console.debug(url); // prints: http://127.0.0.1:57516/

Upvotes: 0

Lin Du
Lin Du

Reputation: 102547

The doc of supertest says:

You may pass an http.Server, or a Function to request() - if the server is not already listening for connections then it is bound to an ephemeral port for you so there is no need to keep track of ports.

You need to pass a Node.js http.Server object to supertest.agent(), then you can use the specific PORT for testing.

Here is the solution:

index.ts:

import express from 'express';
import expressService from './expressService';
import http from 'http';

const app = express();
const PORT = process.env.PORT || 3000;

expressService(app);

function createHttpServer() {
  const httpServer: http.Server = app.listen(PORT, () => {
    console.log('server started at http://localhost:' + PORT);
  });

  return httpServer;
}

if (require.main === module) {
  createHttpServer();
}

export default createHttpServer;

expressService.ts:

import { Application } from 'express-serve-static-core';
import express, { Router } from 'express';
import cors from 'cors';

const expressService = (app: Application) => {
  app.use(cors());
  app.use(express.urlencoded({ extended: true }));
  app.use(express.json());

  const api = Router();

  api.get('/health', (req, res) => {
    res.sendStatus(200);
  });

  app.use(api);
};

export default expressService;

index.spec.ts:

import createHttpServer from './';
import { agent } from 'supertest';
import { omit } from 'lodash';

const httpServer = createHttpServer();
const request = agent(httpServer);

afterAll(done => {
  httpServer.close(done);
});

describe('app', () => {
  it('should return a successful response for GET /health', async () => {
    const res = await request.get('/health');
    res.header = omit(res.header, ['date']);
    expect(res).toMatchSnapshot();
  });
});

Unit test result:

 PASS  src/stackoverflow/57409561/index.spec.ts (7.853s)
  app
    ✓ should return a successful response for GET /health (61ms)

  console.log src/stackoverflow/57409561/index.ts:12
    server started at http://localhost:3000

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        8.66s

Snapshot:

// Jest Snapshot v1

exports[`app should return a successful response for GET /health 1`] = `
Object {
  "header": Object {
    "access-control-allow-origin": "*",
    "connection": "close",
    "content-length": "2",
    "content-type": "text/plain; charset=utf-8",
    "etag": "W/\\"2-nOO9QiTIwXgNtWtBJezz8kv3SLc\\"",
    "x-powered-by": "Express",
  },
  "req": Object {
    "data": undefined,
    "headers": Object {
      "user-agent": "node-superagent/3.8.3",
    },
    "method": "GET",
    "url": "http://127.0.0.1:3000/health",
  },
  "status": 200,
  "text": "OK",
}
`;

Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57409561

Upvotes: 6

Related Questions