如何使用Jest正确对Express 4服务器进行单元测试

时间:2018-12-25 08:55:59

标签: node.js express jestjs supertest

为了更好地理解它,我正在测试此简单的Express服务器(v 4)安装代码:

// server.js

import express from 'express';
import router from './routes';

const app = express();
app.use(router);

const server = app.listen(3000, function () {
  var port = this.address().port;
  /* eslint-disable no-console */
  console.log('Example app listening on port %s!', port);
});

export default app; // as suggested by Ron

使用以下路由器

// route.js

var express = require('express');
var defaultController = require('./controllers/defaultController');

var router = express.Router();

router.get('/', defaultController.getHome);

module.exports = router;

它干净(大衣)并且从头开始运行就很好

我编写了(从2015年编写的tuts中复制/粘贴)以下规范,以使用Jest和SuperTest测试server.js

// server.spec.js

var request = require('supertest');

describe('loading express', function () {
    var server; // http server object

    beforeEach(function () {
        delete require.cache[require.resolve('../src/server')];
        server = require('../src/server');
    });

    afterEach(function () {
        server.close();
    });

    it('responds to /', function testSlash(done) {
        request(server)
          .get('/')
          .expect(200, done);
    });

    it('404 everything else', function testPath(done) {
        request(server)
          .get('/foo/bar')
          .expect(404, done);
    });
});

但是失败了,在.get()上出现类型错误。

  

TypeError:app.address不是函数

并在server.clos()上输入错误

  

TypeError:server.close不是函数

这是完整的控制台。日志

$纱线测试

    yarn run v1.9.4
    $ jest --runInBand --verbose
     FAIL  test/server.spec.js
      loading express
        ✕ responds to / (275ms)
        ✕ 404 everything else (1ms)

      ● loading express › responds to /

        TypeError: app.address is not a function

          16 |     it('responds to /', function testSlash(done) {
          17 |         request(server)
        > 18 |           .get('/')
             |            ^
          19 |           .expect(200, done);
          20 |     });
          21 |

          at Test.Object.<anonymous>.Test.serverAddress (node_modules/supertest/lib/test.js:55:18)
          at new Test (node_modules/supertest/lib/test.js:36:12)
          at Object.obj.(anonymous function) [as get] (node_modules/supertest/index.js:25:14)
          at Object.get (test/server.spec.js:18:12)

      ● loading express › responds to /

        TypeError: server.close is not a function

          11 |
          12 |     afterEach(function () {
        > 13 |         server.close();
             |                ^
          14 |     });
          15 |
          16 |     it('responds to /', function testSlash(done) {

          at Object.close (test/server.spec.js:13:16)

      ● loading express › 404 everything else

        TypeError: app.address is not a function

          22 |     it('404 everything else', function testPath(done) {
          23 |         request(server)
        > 24 |           .get('/foo/bar')
             |            ^
          25 |           .expect(404, done);
          26 |     });
          27 | });

          at Test.Object.<anonymous>.Test.serverAddress (node_modules/supertest/lib/test.js:55:18)
          at new Test (node_modules/supertest/lib/test.js:36:12)
          at Object.obj.(anonymous function) [as get] (node_modules/supertest/index.js:25:14)
          at Object.get (test/server.spec.js:24:12)

      ● loading express › 404 everything else

        TypeError: server.close is not a function

          11 |
          12 |     afterEach(function () {
        > 13 |         server.close();
             |                ^
          14 |     });
          15 |
          16 |     it('responds to /', function testSlash(done) {

          at Object.close (test/server.spec.js:13:16)

      console.log src/server.js:11
        Example app listening on port 3000!

    Test Suites: 1 failed, 1 total
    Tests:       2 failed, 2 total
    Snapshots:   0 total
    Time:        1.062s
    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.

1 个答案:

答案 0 :(得分:0)

对于错误:

  

TypeError:app.address不是函数

  

TypeError:server.close不是函数

更改

var server;
beforeEach(function() {
  delete require.cache[require.resolve('./server')];
  server = require('./server');
});

收件人:

var server;

beforeEach(function() {
  delete require.cache[require.resolve('./server')];
  server = require('./server').default;
});

由于您在server.js文件中启动了HTTP服务器,这意味着当您在测试文件中执行require('./server')语句时,服务器将被启动。完成所有测试后,您应该关闭服务器。否则,将引发错误:

  

错误[ERR_SERVER_NOT_RUNNING]:服务器未运行。

更改

afterEach(function(done) {
  server.close(done);
});

收件人:

afterAll(function(done) {
  server.close(done);
});

app创建的express对象没有.close()方法,但是http.Server有。

更改:

const server = app.listen(3000, function() {
  var port = this.address().port;
  console.log('Example app listening on port %s!', port);
});

export default app;

收件人:

const server = app.listen(3000, function() {
  var port = this.address().port;
  console.log('Example app listening on port %s!', port);
});

export default server;

覆盖率100%的集成测试结果:

☁  jest-codelab [master] ⚡  npx jest --coverage --verbose /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/53920812/server.spec.js
 PASS  src/stackoverflow/53920812/server.spec.js
  loading express
    ✓ responds to / (741ms)
    ✓ 404 everything else (6ms)

  console.log src/stackoverflow/53920812/server.js:428
    Example app listening on port 3000!

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 routes.js |      100 |      100 |      100 |      100 |                   |
 server.js |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.865s, estimated 10s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/53920812