web-dev-qa-db-ja.com

Mocha / Chaiでテストが拒否された約束

私は約束を拒否するクラスを持っています:

Sync.prototype.doCall = function(verb, method, data) {
  var self = this;

  self.client = P.promisifyAll(new Client());

  var res = this.queue.then(function() {
    return self.client.callAsync(verb, method, data)
      .then(function(res) {
        return;
      })
      .catch(function(err) {    
        // This is what gets called in my test    
        return P.reject('Boo');
      });
  });

  this.queue = res.delay(this.options.throttle * 1000);
  return res;
};

Sync.prototype.sendNote = function(data) {
  var self = this;
  return self.doCall('POST', '/Invoice', {
    Invoice: data
  }).then(function(res) {
    return data;
  });
};

私のテストでは:

return expect(s.sendNote(data)).to.eventually.be.rejectedWith('Boo');

ただし、テストに合格すると、コンソールにエラーがスローされます。

未処理の拒否エラー:ブー...

非プロミスエラーでは、バインドテストを使用して、Chaiがラップしてテストできるまでエラーがスローされないようにしました。

return expect(s.sendNote.bind(s, data)).to.eventually.be.rejectedWith('Boo');

ただし、これはこれでは機能せず、次を返します:

TypeError:[Function] is not a thenable.

これをテストする正しい方法は何ですか?

14
cyberwombat

SendNoteが拒否され、キャッチできないため、エラーが発生します。

試してください:

var callPromise = self.doCall('POST', '/Invoice', {
  Invoice: data
}).then(function(res) {
  return data;
});

callPromise.catch(function(reason) {
  console.info('sendNote failed with reason:', reason);
});

return callPromise;

既存のキャッチを1ブロック外に移動する必要があるようです。

var res = this.queue.then(function() {
  return self.client.callAsync(verb, method, data)
    .then(function(res) {
      return;
    });
  }).catch(function(err) {    
    // This is what gets called in my test    
    return P.reject('Boo');
  });
5
rrowland

(免責事項:これはBluebirdを使用していない人にとっても良い質問です。同様の回答を投稿しました here ;この回答はBluebirdを使用していない人でも機能します。)

約束通りのチャイ

Chai-as-promisedを使用して、Promiseのresolverejectの両方のケースをテストする方法は次のとおりです。

var chai = require('chai');
var expect = chai.expect;
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);

...

it('resolves as promised', function() {
    return expect(Promise.resolve('woof')).to.eventually.equal('woof');
});

it('rejects as promised', function() {
    return expect(Promise.reject('caw')).to.be.rejectedWith('caw');
});

約束通りのチャイなし

次のように約束されたchaiなしで同じことを達成できます。

it('resolves as promised', function() {
  return Promise.resolve("woof")
    .then(function(m) { expect(m).to.equal('woof'); })
    .catch(function(e) { throw e })  // use error thrown by test suite
           ;
});

it('rejects as promised', function() {
    return Promise.reject("caw")
        .then(function(m) { throw new Error('was not supposed to succeed'); })
        .catch(function(m) { expect(m).to.equal('caw'); })
            ;
});
21
fearless_fool

私は個人的にそのイディオムを使用しています:

_it('rejects as promised', function() {
    return Promise.reject("caw")
        .then(
          (m) => { assert.fail('was not supposed to succeed'); }
          (m) => { /* some extra tests here */ }
        );
});
_

これは、then(onFulfilled, onRejected)(2つの引数)を使用するのが正当なまれなケースの1つです。

他の回答で提案されているように.then(reject).catch(onRejected)をチェーンすると、最終的にcatchハンドラーに入力することになります毎回これは、前で生成された拒否もキャッチするためですthenハンドラー-その結果をチェックするのに十分注意しないと、常緑のテストを引き起こす可能性があります。

8
Sylvain Leroux

私は同じ問題に直面しましたが、多くのハックを行ったときに、モカで拒否された約束をテストするための解決策を見つけました。

以下のようにモカコードを記述

it('works with resolved and rejected promises', function() {
 return yourPromiseFunction("paramifrequired")
       .then((result)=>{
            //check with should or expect
       }).catch((result)=>{
            //check with should or expect whether it's rejected with proper result status. set result status in promise function while rejecting accordingly
       })

  });

注:-役立つと思います。別のアイデアの提案がある場合はコメントしてください私はjsの世界を探索する初心者です

0