web-dev-qa-db-ja.com

モカテストの開始前にサーバーアプリが実行されるようにする

これは 各モカテストの前に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()
    })
  })
10
Kannaj

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つ以上のテストスイートでサーバーが必要な場合に役立ちます)。

15
xmikex83

ソリューションは説明しました ここ は私のために特に働きました:

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に詳細が含まれています。

それが役に立てば幸い !

11
santiago

サーバーが指定されたポートで実際に待機するまで待機する必要があります。これは、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
scthi

私は最初の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の専門家ではありませんが、これでうまくいきます。それが役に立てば幸い!

0
liu liu