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

时间:2016-07-06 11:35:26

标签: javascript node.js express mocha

这类似于Ensuring Express App is running before each Mocha Test,但指定的解决方案仍然无效+我正在使用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()
    })
  })
})

以上似乎不起作用。尽管提供了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()
    })
  })

4 个答案:

答案 0 :(得分:12)

您的server模块没有回调功能,因此当您在done()方法中调用beforeEach时,该模块无法就绪。

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

答案 1 :(得分:7)

解决方案解释here为我工作,特别是:

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

Calendar date = Calendar.getInstance();
date.set(2017, Calendar.SEPTEMBER, 16);
date.add(Calendar.DAY_OF_MONTH, 7 - (date.get(Calendar.DAY_OF_WEEK) - 1));

System.out.println(date.get(Calendar.DAY_OF_MONTH));    // prints "17"

并在test.js中:

gpg --decrypt --passphrase="${PASSWORD}" \
    /path/to/encrypted/file > /path/to/unencrypted/file

在这种情况下,应用会发送" app_started"正在监听的事件,测试代码等待它。提供的URL包含更多详细信息。

希望它有所帮助!

答案 2 :(得分:2)

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

在您的server.js

let initCallback;

[..]

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


exports = {
  init: function(cb) {
    initCallback = cb;
  }
}

在你的考试中

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

另见:How to know when node.js express server is up and ready to use

答案 3 :(得分:0)

我结合了前两个帖子,它对我有用。 首先,确保你的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;
  }
}




接下来在test.js中你将需要这个



//beginning of your code
const app = require("../../server/server").app;
before(done => {
  require("../app").init();
  done();
});



//end of your code
  after(done => {
  done();
});




我不是javascript的专家,但这对我有用。希望能帮助到你!