确保服务器应用程序在摩卡testing开始之前运行

这与在每次摩卡testing之前确保快速应用程序运行相似,但指定的解决scheme仍然无法正常工作+我正在使用websocket服务器

总之,我使用一个名为socketcluster的websocket框架,这是我的服务器文件

import {SocketCluster} from 'socketcluster'; const socketCluster = new SocketCluster({ workers:1, brokers:1, port: 3000, appName:null, initController: __dirname + '/init.js', workerController: __dirname + '/worker.js', brokerController: __dirname + '/broker.js', socketChannelLimit: 1000, crashWorkerOnError: true }) export default socketCluster 

运行node server.js启动worker.js中指定的工作进程

 export const run = (worker) => { console.log(' >> worker PID: ',process.pid); const app = express(); const httpServer = worker.httpServer; const scServer = worker.scServer; app.use(cookieParser()) httpServer.on('request', app); app.get('/',(req,res) => { console.log('recieved') res.send('Hello world') }) } 

我想testing服务器,但在服务器实际启动之前testing正在完成(和失败)。 有没有一种方法可以强制服务器完全加载前进行testing? 这是我迄今为止

 describe('Express server',() =>{ beforeEach((done) => { require('../../server/server') done() }) it('should return "Hello World"',(done) => { http.get('http://127.0.0.1:3000',(res) => { expect(res).to.contain('wtf world') done() }) }) }) 

上面似乎没有工作。 即使提供了done()调用,服务器也不会完全加载前一个块。

编辑 – 我已经尝试拆分server.js文件来调用不同的服务器基于如何导入。

 const main = () => { console.log('main server') new SocketCluster({ workers:1, brokers:1, port: 3000, appName:null, initController: __dirname + '/init.js', workerController: __dirname + '/worker.js', brokerController: __dirname + '/broker.js', socketChannelLimit: 1000, crashWorkerOnError: true }) } export const test = (port,done) => { console.log('testing server') new SocketCluster({ workers:1, brokers:1, port: port, appName:null, initController: __dirname + '/init.js', workerController: __dirname + '/worker.js', brokerController: __dirname + '/broker.js', socketChannelLimit: 1000, crashWorkerOnError: true }) done() } if (require.main === module){ main() } 

并在test.js,我这样做 – 但似乎仍然工作

 import {expect} from 'chai'; import {test} from '../../server/server' describe('Express server',() =>{ before(function(done){ test(3000,done) }) it('should return "Hello World"',(done) => { http.get('http://127.0.0.1:3000',(res) => { expect(res).to.contain('world') done() }) }) }) 

编辑:2 – 另一种方式从server.js文件返回一个承诺。 仍然没有工作

 export const test = (port) => { console.log('testing server') return Promise.resolve(new SocketCluster({ workers:1, brokers:1, port: port, appName:null, initController: __dirname + '/init.js', workerController: __dirname + '/worker.js', brokerController: __dirname + '/broker.js', socketChannelLimit: 1000, crashWorkerOnError: true })) } 

并在之前挂钩

  before(function(done,port){ test(3000).then(function(){ console.log('arguments: ',arguments) done() }) }) 

您的server模块没有callback,所以当您在beforeEach方法中调用done()时,它不能做好准备。

首先,将您的app导出到您的server模块中。

然后,做一些事情:

 const app = require('../../server/server').app; let server; before(done => { server = app.listen(3000, done); }); /** ... your tests here ... **/ /** and, if you need to close the server after the test **/ after(done => { server.close(done); }); 

这样, done()将在listencallback中被调用,所以在你的testing中服务器将会正确的收听。 然后,记住在testing结束后closures它(如果需要在一个或多个testing套件中使用服务器,则有用)。

您需要等到服务器实际侦听给定的端口。 这可以通过在server.js中导出某种init函数来完成,该函数从mocha完成callback。

在你的server.js

 let initCallback; [..] app.listen(port, function() { if (initCallback) { initCallback(); } }); exports = { init: function(cb) { initCallback = cb; } } 

在你的testing中

 beforeEach((done) => { require('../../server/server').init(done) }) 

另请参阅: 如何知道node.js express服务器何时启动并可以使用

我组合了前两个职位,并为我的工作。 首先,确保你的app.js或server.js中有init代码

 // put this in the beginning of your app.js/server.js let initCallback; //put this in the end of your app.js/server.js if (initCallback) { // if this file was called with init function then initCallback will be used as call back for listen app.listen(app.get('port'),"0.0.0.0",(initCallback)=>{ console.log("Server started on port "+app.get('port')); }); } else{ // if this file was not called with init function then we dont need call back for listen app.listen(app.get('port'),"0.0.0.0",()=>{ console.log("Server started on port "+app.get('port')); }); } //now export the init function so initCallback can be changed to something else when called "init" module.exports = { init: function(cb) { initCallback = cb; } } 

这里解释的解决scheme对我来说尤其有效:

在server.js(或app.js)的末尾:

 app.listen( port, ip, function() { console.log( 'Server running on http://%s:%s', ip, port ) app.emit( "app_started" ) }) module.exports = app 

并在test.js中:

 var server = require( '../server' ) before( done => { server.on( "app_started", function() { done() }) }) 

在这种情况下,应用程序在侦听时发送一个“app_started”事件,并且testing代码等待。 提供的URL包含更多的细节。

希望能帮助到你 !