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