2016-07-06 92 views
2

这类似于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() 
    }) 
    }) 

回答

6

server模块没有回调,所以当你在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()将被称为在listen回调,所以在您的测试服务器将正确地听着。然后,请记住在测试结束后关闭它(如果需要在一个或多个测试套件中使用服务器,则有用)。

+0

感谢您的回答..但它看起来像监听方法是在socketcluster源代码内建的地方。 :/看起来像改变node_modules源是唯一的选择 – Kannaj

+0

我做了一些改变的代码..可以通过类似的方式实现解决方案?仍然似乎没有工作,虽然 – Kannaj

2

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

在您的服务器上。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

+0

我做了一些更改的代码..可以解决方案以类似的方式实现?仍然似乎没有工作,虽然 – Kannaj

+0

SocketCluster发出一个准备好的事件,这应该做的伎俩。请参阅:https://github.com/SocketCluster/socketcluster/blob/b0e8438a3cf8816a9b5825196c5a2f0e87bffbeb/test/external/server.js – scthi

0

我结合前两个职位,它的工作对我的。 首先,确保你已经初始化代码在你app.js或在您的test.js server.js

// 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; 
 
    } 
 
}

接下来,您将需要此

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

 

 

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

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

1

溶液解释here为我工作,尤其是:

在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”事件,并且测试代码等待它。提供的URL包含更多详细信息。

希望它有帮助!

+0

也为我工作,谢谢 – migueloop