超级测试在每次测试中更改 url

supertest changing url at every test

我是后端开发的新手,我遇到了一个我不明白的问题。

我设置了我的 API 的第一个路由叫 "health" 谁只是 return 一个简单的消息来知道我的服务器是否启动。

这条路线看起来像预期的那样工作。

然而,

当我尝试使用方法 "toMatchSnapshot" 测试这条路线时 开玩笑 API,由于 url 中的不断变化,测试未通过。

我的测试文件"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.ts":

const app = express();

expressService(app);

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

export default app;

我的函数"expressService":

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

    app.use(api);
};

export default expressService;

我的 PORT 变量:PORT = 3000;

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

这是测试失败的地方。

感谢您的回答。

supertest 的文档说:

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.

您需要传递一个Node.js http.Server对象给supertest.agent(),然后您可以使用特定的PORT进行测试。

解决方法如下:

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();
  });
});

单元测试结果:

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

  console.log src/Whosebug/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

快照:

// 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",
}
`;

这是完成的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/57409561

足够简单的解决方案:

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/