如何在使用 mocha 和 chai 的测试之间正确关闭 Express 服务器

问题描述 投票:0回答:3

我正在寻找一种正确的方法来在测试之间完全重置我的快递服务器!看来这不仅仅是我的问题,很多其他用户也问过同样的问题, 许多博客文章都围绕这个论点撰写。所提出的解决方案对我来说既不起作用也不令人满意。这里还有另一个类似的问题和一篇文章,很好地描述了该问题并提出了一些解决方案:

堆栈溢出 运行 jasmine 规范后关闭 Express 服务器

博客: https://glebbahmutov.com/blog/how-to- Correctly-unit-test-express-server/

这里专门创建了一个包来解决这个问题: https://www.npmjs.com/package/server-destroy

现在,一个最小的工作示例来重现我的情况。 在被测代码中,创建了一个express服务器;当在某个端点上调用时,服务器会增加一个值并返回它:

( function() {
   'use strict'

   const enableDestroy = require( 'server-destroy' )
   const app = require( 'express' )()
   const http = require( 'http' )

   let val = 0

   app.use( '/inc', (req, res) => {
      val ++
      res.send(val.toString())
   } )

   const server = http.createServer( app )

   server.listen( 3000 )

   enableDestroy(server);

   module.exports = server

} )()

测试由两个相同的测试用例组成;他们都调用端点上的服务器,并检查返回的值。 提供

before_each
after_each
部分是为了确保在运行单个测试用例之前创建新连接,然后关闭,以确保两个测试用例之间的独立性:

const chai = require( 'chai' )
const chaiHttp = require( 'chai-http' )
const expect = chai.expect
chai.use( chaiHttp )

let server

describe( 'first test group', () => {
   beforeEach( () => {
      server = require( './server' )
   } ),

   afterEach( ( done ) => {
      server.destroy( done )
      delete require.cache[require.resolve( './server' )]
   } ),

   it( 'should respond 1', ( done ) => {
      chai.request( server )
         .get( '/inc' )
         .set( 'Connection', 'close' )
         .end( ( err, res ) => {
            expect( res.text ).to.be.equal( '1' )
            done()
         } )
   } ),

   it( 'should respond 1', ( done ) => {
      chai.request( server )
         .get( '/inc' )
         .set( 'Connection', 'close' )
         .end( ( err, res ) => {
            expect( res.text ).to.be.equal( '1' )
            done()
         } )
   } )
} )

测试失败,因为服务器在第一次测试后“未运行”。请注意,在 after_each 部分中,我强制清理缓存以完全丢失最后一个服务器实例。如果运行单个测试用例,则测试成功:


first test group ✓ should respond 1 1) "after each" hook for "should respond 1" 1 passing (70ms) 1 failing 1) first test group "after each" hook for "should respond 1": Error: Not running at Server.close (net.js:1620:12) at emitCloseNT (net.js:1671:8) at _combinedTickCallback (internal/process/next_tick.js:135:11) at process._tickCallback (internal/process/next_tick.js:180:9)

我使用的配置:

节点8.11.1
  • 快报:“4.16.3”
  • 摩卡5.0.5
  • 柴4.1.2
  • chai-http 4.0.0
  • 如何解决这个问题?错误消息是什么意思?

node.js express mocha.js chai chai-http
3个回答
8
投票
server-destroy

因为

server.close
效果很好

服务器.js

// ( function() { // no need for this 'use strict' //const enableDestroy = require( 'server-destroy' ) const app = require( 'express' )() const http = require( 'http' ) let val = 0 app.use( '/inc', (req, res) => { val ++ res.send(val.toString()) } ) const server = http.createServer( app ) server.listen( 3000 ) // enableDestroy(server); module.exports = server // } )()

测试.js

const chai = require( 'chai' ) const chaiHttp = require( 'chai-http' ) const expect = chai.expect chai.use( chaiHttp ) let server describe( 'first test group', () => { beforeEach( () => { server = require( './server' ) } ), afterEach( ( done ) => { // UPDATE DON'T CLOSE THE SERVER delete require.cache[require.resolve( './server' )] done() //server.close( () => { // delete require.cache[require.resolve( './server' )] // done() //}) } ), it( 'should respond 1', ( done ) => { chai.request( server ) .get( '/inc' ) .set( 'Connection', 'close' ) .end( ( err, res ) => { expect( res.text ).to.be.equal( '1' ) done() } ) } ), it( 'should respond 1', ( done ) => { chai.request( server ) .get( '/inc' ) .set( 'Connection', 'close' ) .end( ( err, res ) => { expect( res.text ).to.be.equal( '1' ) done() } ) } ) } )



1
投票

在 chai-http 文档中,我可以发现它具有使用请求方法中的

keepOpen()

方法打开服务器连接的机制。 (实际上它返回一个代理)

const chai = require("chai");
const chaiHttp = require("chai-http");

chai.use(chaiHttp);

const chaiAppServer = chai.request(server).keepOpen();

https://www.chaijs.com/plugins/chai-http/#integration-testing

但是正如它提到的,我们必须手动关闭服务器连接。

describe("TEST Case group", () => { after(() => { chaiAppServer.close(); }); //..... integration test cases });



0
投票
--exit

添加到运行测试的 mocha 命令中。无需

after()
块。
我的 package.json 脚本:

"test:integration": "mocha --timeout 5000 --exit -r ts-node/register test/integration/*.spec.ts",

我的测试脚本中唯一需要的是 
before()

函数,无需清理。

import chai, { expect } from 'chai';
import chaiHttp from 'chai-http';

chai.use(chaiHttp);
describe.only('some-test', function () {
  let requestor: ChaiHttp.Agent;

  before(function (done) {
    requestor = chai.request(app).keepOpen();
    done();
  });
...

	
© www.soinside.com 2019 - 2024. All rights reserved.