为什么 Jest 无法识别具有 Express.js 的服务器实例?

Why Jest doesn't recognise Server instance with Express.js?

首先,我是一个初学者。我使用 express-generator 创建了一个 Express 项目,其中包含一个文件:bin/www。 www 实际上是一个包含服务器创建的 javascript 文件,如下面的代码片段:

#!/usr/bin/env node

// This file is generated by express generator

var app = require('../app');
var debug = require('debug')('happy-meal:server');
var http = require('http');


var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

var server = http.createServer(app);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

function normalizePort(val) {}
function onError(error) {}
function onListening() {}

// Added by myself
exports.module = server;

我自己添加的最后一行是为了在 jest 测试中访问服务器实例。

所以,我想 运行 使用以下代码进行简单的集成测试:

// integration test: users.test.js
const request = require("supertest");

describe("/api/v1/users", () => {

    let server;

    beforeEach(() => {
        server = require("../../bin/www");
    });
    afterEach(() => {
        server.close();
    });

    describe("GET /", () => {
        it("should return all users", async (done) => {
            const res = await request(server).get("/api/v1/users");

            expect(res.status).toBe(200);
            done();
        });
    });
});

这导致了 jest 的以下错误输出:

TypeError: app.address is not a function

      14 |     describe("GET /", () => {
      15 |         it("should return all users", async (done) => {
    > 16 |             const res = await request(server).get("/api/v1/users");
         |                                               ^
      17 | 
      18 |             expect(res.status).toBe(200);
      19 |             done();

      at Test.serverAddress (node_modules/supertest/lib/test.js:55:18)
      at new Test (node_modules/supertest/lib/test.js:36:12)
      at Object.get (node_modules/supertest/index.js:25:14)
      at Object.<anonymous> (tests/integration/users.test.js:16:47)

  ● /api/v1/users › GET / › should return all users

    TypeError: server.close is not a function

       9 |     });
      10 |     afterEach(() => {
    > 11 |         server.close();
         |                ^
      12 |     });
      13 | 
      14 |     describe("GET /", () => {

      at Object.<anonymous> (tests/integration/users.test.js:11:16)

它似乎无法将 "server" 变量识别为服务器对象。因此,"server.close()" 不起作用,结果服务器没有关闭。 get-request 也不起作用。再一次,服务器对象不被视为服务器实例。

我做错了什么?我希望你能在这里帮助我。

request(server) 不起作用,您必须改用 app 实例:

const app = require('../../app'); // Where your app instance is

...

const res = await request(app).get("/api/v1/users");

此外,首先尝试导入您的服务器,看看它是否被识别为服务器对象。

编辑

要么你想在每次测试时都创建 http 服务器,要么你想为所有测试创建一次 http 服务器,然后在测试结束后关闭它。试试这个:

// integration test: users.test.js
const http = require('http');
const request = require("supertest")
const app = require('../../app'); // Where your app instance is

describe("/api/v1/users", () => {
  beforeAll(done => {
      server = http.createServer(app);
      server.listen(done);
  });

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

  describe("GET /", () => {
        it("should return all users", async (done) => {
            const res = await request(app).get("/api/v1/users");

            expect(res.status).toBe(200);
            done();
        });
    });
});