これは 各モカテストの前にExpressアプリが実行されていることを確認 に似ていますが、指定されたソリューションはまだ機能していません+ 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()呼び出しも提供しているにもかかわらず、サーバーはbeforeブロックで完全にロードされません。
edit-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()
})
})
})
edit:2-server.jsファイルからpromiseを返すことで別の方法を試してください。まだ動かない
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フックで
before(function(done,port){
test(3000).then(function(){
console.log('arguments: ',arguments)
done()
})
})
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
コールバックで呼び出されるため、テストではサーバーが正しくリッスンします。次に、テストの終了後に必ず閉じてください(1つ以上のテストスイートでサーバーが必要な場合に役立ちます)。
ソリューションは説明しました ここ は私のために特に働きました:
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に詳細が含まれています。
それが役に立てば幸い !
サーバーが指定されたポートで実際に待機するまで待機する必要があります。これは、mochaから完了コールバックを取得する、server.jsのある種のinit関数をエクスポートすることで実現できます。
あなたのserver.js
let initCallback;
[..]
app.listen(port, function() {
if (initCallback) {
initCallback();
}
});
exports = {
init: function(cb) {
initCallback = cb;
}
}
あなたのテストで
beforeEach((done) => {
require('../../server/server').init(done)
})
また参照してください: node.jsエクスプレスサーバーが稼働していて使用できる状態になっていることを知る方法
私は最初の2つの投稿を結合し、それは私ののために働いた。まず、app.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;
}
}
次に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の専門家ではありませんが、これでうまくいきます。それが役に立てば幸い!