2016-07-06 84 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

相關問題