3

これは、Mocha を使用した Sails JS での非同期テストに関する質問です。

スーパーテスト ライブラリを使用して、Sails JS でコントローラー テストを作成しています。コントローラーへの HTTP POST でメソッドが呼び出されているかどうかを確認したいと思います。end()そのために、メソッドをスタブ化し、次のように呼び出されることを期待しています。

request(sails.hooks.http.app)
    .post('heartbeat/create')
    .send('device: 1')
    .end(function(err, res) {
        expect(publishCreateStub.called).to.be.true;
        done();
    });

これを実行すると、アサート時にメソッドが呼び出されないため、期待は失敗します。しかし、次のように期待を入れると、setTimeoutうまくいきます:

request(sails.hooks.http.app)
    .post('heartbeat/create')
    .send('device: 1')
    .end(function(err, res) {
        setTimeOut(function() {
            expect(publishCreateStub.called).to.be.true;
            done();
        }, 1000);
    });

なしでテストに合格する方法はありますsetTimeoutか?

ここに私がテストしているコード部分があります: HeartbeatController#create

プルリクエストを送信して問題を解決することもできます: https://github.com/multunus/one-mdm/issues/1

4

2 に答える 2

3

publishCreate実際の問題は、コントローラーが呼び出されるのを待たないことです。201 Createdしたがって、何かが作成されたことを確認せずに応答しています。

またはどちらHeartbeat.findOneHeartbeat.publishCreateが失敗する可能性がありますが、それは後でわかります。

この問題を解決するには、コントローラーを変更して、応答部分をHeartbeatpromise コールバック内に移動する必要があります。

create: function (req, res, next) {
  if(req.isSocket) {
    Heartbeat.watch(req);
  }

  Heartbeat.create(req.body)
    .exec(function(error, heartbeat) {
      if(error) {
        res.status(422);
        return res.send('Invalid heartbeat data');
      }

      Heartbeat.findOne(heartbeat.id).populate('device').then(function(newHeartbeat) {
        Heartbeat.publishCreate(newHeartbeat.device);
      }).then(function() {
        // success
        res.status(201);
        res.json({
          device: heartbeat.device
        });
      }, function(err) {
        // something bad happened
        next(err);
       });

    });
}

私の例では、実際のエラー処理を次の高速エラー処理ミドルウェアに委譲しています。

next(err);

ただし、代わりにエラーを自分で処理することもできます。たとえば、次のようになります。

res.status(400);
res.send('Can not publish Heartbeat create');
于 2014-11-24T09:57:48.737 に答える