Javascript 确保服务器应用程序在mocha测试开始前运行

Javascript 确保服务器应用程序在mocha测试开始前运行,javascript,node.js,express,mocha.js,Javascript,Node.js,Express,Mocha.js,这与类似,但指定的解决方案仍然不起作用+我正在使用websocket服务器 简而言之,我正在使用一个名为socketcluster的websocket框架,这是我的服务器文件 import {SocketCluster} from 'socketcluster'; const socketCluster = new SocketCluster({ workers:1, brokers:1, port: 3000, appName:null, initController:

这与类似,但指定的解决方案仍然不起作用+我正在使用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')
  })

}
我想测试服务器,但是测试在服务器实际启动之前就已经完成(并且失败了)。在进行测试之前,有没有办法强制服务器完全加载?这就是我目前所拥有的

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()
    })
  })
})
以上这些似乎不起作用。服务器在before块中没有完全加载,尽管也提供了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()
    })
  })

您的
服务器
模块没有回调,因此在您的
beforeach
方法中调用
done()
时,它无法准备就绪

首先,在
服务器
模块中导出
应用程序

然后,做一些类似的事情:

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()
将在
listen
回调中被调用,因此在测试中服务器将正确地侦听。然后,请记住在测试结束后关闭它(如果一个或多个测试套件中需要服务器,则此功能非常有用)。

您需要等待服务器实际侦听给定端口。 这可以通过在server.js中导出某种init函数来实现,该函数接受来自mocha的done回调

在您的server.js中

let initCallback;

[..]

app.listen(port, function() {
  if (initCallback) {
    initCallback();
  }
});


exports = {
  init: function(cb) {
    initCallback = cb;
  }
}
在你的测试中

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

另请参见:

我将前两篇文章合并在一起,这对我的文章起到了作用。 首先,确保app.js或server.js中有init代码

let initCallback;

[..]

app.listen(port, function() {
  if (initCallback) {
    initCallback();
  }
});


exports = {
  init: function(cb) {
    initCallback = cb;
  }
}
//将其放在app.js/server.js的开头
让我们重新开始;
//把这个放在app.js/server.js的末尾
if(initCallback){
//如果此文件是使用init函数调用的,则initCallback将用作侦听的回调
app.listen(app.get('port'),“0.0.0.0”,(initCallback)=>{
console.log(“服务器在端口上启动”+app.get(“端口”);
});
}
否则{
//如果这个文件不是用init函数调用的,那么我们就不需要为listen回调
app.listen(app.get('port'),“0.0.0.0”,()=>{
console.log(“服务器在端口上启动”+app.get(“端口”);
});
}
//现在导出init函数,以便在调用“init”时可以将initCallback更改为其他函数
module.exports={
初始化:函数(cb){
initCallback=cb;
}
}
所解释的解决方案对我很有效,特别是:

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

在test.js中:

var server = require( '../server' )
before( done =>
{
  server.on( "app_started", function()
  {
    done()
  })
})
在这种情况下,应用程序在侦听时发送一个“app_start”事件,测试代码等待它。提供的URL包含更多详细信息


希望有帮助

谢谢你的回答。。但看起来listen方法是在socketcluster源代码中内置的看起来更改节点_模块中的源代码是唯一的选择。我对代码做了一些更改。。能否以类似的方式实现解决方案?如果有多个测试文件,我应该在每个测试文件中使用
之前的
钩子吗?我对代码做了一些更改。。能否以类似的方式实现解决方案?尽管SocketCluster发出一个ready事件,但它似乎仍然不起作用,这应该会起作用。看,这对我不起作用。给出
错误:超时超过2000ms。对于异步测试和挂钩,确保调用“done()”;如果返回承诺,请确保它已解决。
在“before\u all”钩子中。我认为这是因为发射器和on不在同一个变量上@nikThis适用于我,但我在发出事件时必须使用setTimeout。