Mocha: 非同期テストがアサヌション゚ラヌではなくタむムアりトで倱敗する

䜜成日 2014幎02月05日  Â·  25コメント  Â·  ゜ヌス: mochajs/mocha

このテスト

    it('returns the correct value', function(done) {
      var returnValue = 5;

      aPromise.then(function() {
        expect(returnValue).to.equal(42);
        done();
      });

    });

このテストは、アサヌション゚ラヌではなくtimeout of 2000ms exceeded倱敗したす。 これは、 expect()呌び出しが゚ラヌをスロヌし、 done()が実行されないためだず思いたす。この皮のコヌドをテストするための、より良い方法があるかどうか疑問に思っおいたす。

最も参考になるコメント

私は同様の問題に遭遇し、最終的に、promiseを䜿甚しお非同期関数をテストするずきにdoneを䜿甚するべきではなく、promiseを返すだけであるこずに気付きたした。 したがっお、タむムアりトなしでこれを実行できるはずです。䟋

it('returns the correct value', function() {
    var returnValue = 5;

    return aPromise.then(function() {
        expect(returnValue).to.equal(42);
    });
});

党おのコメント25件

aPromise解決したすか そうでない堎合は、タむムアりトをスロヌする以倖に遞択肢はありたせん。

@NickHeinerはい、解決したす。 次に、 expect()は、 returnValueがequal(42)ではないこずを怜出し、スロヌしたす。

@gurdigaアサヌション゚ラヌではなくタむムアりトが発生した堎合にスロヌされるこずをどのように知っおいたすか

@hallas @NickHeinerこれが実行䞭のものです http  //jsfiddle.net/gurdiga/p9vmj/ 。

@gurdigaあなたの玄束には独自の゚ラヌキャッチがあるように私には思えたす。 玄束に.catch(done)を远加しおみおください。そうすれば、意図したずおりに機胜するず思いたす。

@hallasうわヌ_それ_が答えでした :) aPromise.finally()は、 doneを入れるのに最適なようですpromiseが解決されたずきに呌び出す必芁もありたす。 ;

ありがずうございたした

私は愚かだず感じたす。

私は぀いにそれを手に入れたず思いたす .then() 、 .catch()たたは.finally()に枡されたものであるかどうかにかかわらず、promiseのハンドラヌ関数のいずれかで䜕かがスロヌされるず、゚ラヌはpromiseラむブラリによっお凊理されたす。 このように、テストランナヌは実際の゚ラヌを芋るこずはなく、 done()が呌び出されるこずもありたせんアサヌション゚ラヌをスロヌする前に䜕かが発生したため。したがっお、タむムアりト゚ラヌはテストランナヌから埗られるすべおです。

玄束から抜け出すために、私はsetTimeout()を䜿甚したす

    it('returns the correct value', function(done) {
      var returnValue = 5;

      aPromise.then(function() {
        setTimeout(function() {
          expect(returnValue).to.equal(42);
          done();
        });
      });
    });

これが適切な゚ラヌメッセヌゞを取埗しおランナヌの動䜜をテストする唯䞀の方法であるこずがわかりたした。

doneが.catch()たたは.finally()に枡されるず、どのような堎合でもテストに合栌したず芋なされるため、アサヌション゚ラヌが発生した堎合、それらは衚瀺されたせん。

私は同様の問題に遭遇し、最終的に、promiseを䜿甚しお非同期関数をテストするずきにdoneを䜿甚するべきではなく、promiseを返すだけであるこずに気付きたした。 したがっお、タむムアりトなしでこれを実行できるはずです。䟋

it('returns the correct value', function() {
    var returnValue = 5;

    return aPromise.then(function() {
        expect(returnValue).to.equal(42);
    });
});

この問題はただ存圚しおいるず思いたす。 モゞュヌルがpromiseを䜿甚しおいないため、promiseを返すこずで解決できないタむムアりトの問題が発生したす。

it("works", function(done) {
    new Something()
    .on("eventA", function(result) {
        expect(result).to.be.true;
    })
    .on("eventB", function(result) {
        expect(result).to.be.false;
        done();
    });
});
  • むンスタンスをPromiseでラップするのは過剰なようです。
  • 各アサヌションをtry / catchラップするこずも過剰に思え、さらに重芁なこずに、結果はError: done() called multiple timesたす。

アむデア
http://staxmanade.com/2015/11/testing-asyncronous-code-with-mochajs-and-es7-async-await/

ブログ投皿の掚奚事項に関しおは、非同期関数の゚ラヌ凊理に぀いおはわかりたせんが、単玔なpromiseの堎合、try-catchの掚奚事項は奇劙です。try-catchを䜿甚しない元のpromiseの詊行はほが正しく、 .catch(done)を䜿甚するだけで枈みたした。 thenの2番目のパラメヌタヌを.catch(done) done 。 確かに、Mochaはpromiseを盎接サポヌトしおいるので、promiseを返すこずもできたすが、その䟡倀はありたす...最初のpromiseの䟋の問題は、try-catchがないこずではなく、2番目のハンドラヌでした。 to thenは、最初のハンドラヌによっおスロヌされた䟋倖を陀いお呌び出されたせんが、次のcatchは呌び出されたす。 玄束がそのように蚭蚈される理由が䜕であったかはわかりたせんが、それは玄束がどのようであるかです。 さらに、䜕らかの理由で耇数のthenがあった堎合、必芁なのは1぀の最埌の.catch(done)だけです。これは、ハンドラヌ内のtry-catchよりも優れおいる点です .catch(done)は、そもそも定型的ではないずいう事実。

APIに぀いお

  1. 䞡方のむベントが正しい順序で呌び出されおいるこずを確認したすか そうでない堎合、あなたのテストはどのようにそれを通垞の倱敗に倉えたすか
  2. むベントハンドラからスロヌされる䟋倖は通垞どうなりたすか それらが同期コヌドのように䌝播せず、代わりにAPIでリッスンされるこずを意図しおいる堎合たずえば.on("error", function(error) {...}) 、それらをリッスンしお持っおいない限り、Mochaに到達するこずはありたせん。リスナヌぱラヌでdoneを呌び出したすたたは、リスナヌに゚ラヌが最初のパラメヌタヌずしお枡された堎合は、リスナヌでdoneを䜿甚したす䟋 .on("error", done) 。 promiseの.catch(done)ように、むベントハンドラヌごずに1回ではなく、テストごずに1回蚘述する必芁がありたす。
  1. はい。 "end" / "drain"むベントを䜿甚しお、他のむベントのブヌル倀が蚭定されおいるかどうかを確認したす。
  2. タむムアりトが発生したす。 私は無駄のないクリヌンな代替品を芋぀けようずしおいたす。

申し蚳ありたせんが、APIがどのように゚ラヌを報告するのかただわかりたせん。

ええ、これたでのずころ、䜕かが倱敗したずきのタむムアりトに䟝存しおいお、手動で掘り䞋げお_how / why_を芋぀けおきたした。 幞いなこずに、物事が壊れるこずはめったにありたせんが、それはより良いデザむンの欠劂の蚀い蚳にはなりたせん私の偎では、ほずんど。

@stevenvachon 事前に蚱しおください。しかし、あなたの䟋にすぐに問題が発生するこずはありたせん。 むベントリスナヌで行われたアサヌションは、 uncaughtExceptionマッピングを介しおMochaによっお凊理される必芁がありたすむベント゚ミッタヌの実装がリスナヌ゚ラヌをキャッチし、 errorむベントなどを発行しおいる堎合を陀きたす。これでも、簡単に実行できたす。解決。

これで、内郚での実装がPromisesを䜿甚しおいるが、Promiseを公開するのではなくむベントを発行する堎合、アサヌションは実際に「食べられる」こずになりたす。 この問題を回避する方法は、 unhandledRejectionを䜿甚するこずです。

私は通垞、これをテストの前に実行されるセットアップスクリプトに入れたす。

process.on('unhandledRejection', function (reason)
{
    throw reason;
});

泚ブラりザで機胜させるには、远加の゚ルボヌグリヌスが必芁になる堎合がありたす。

これは䞀般的なナヌスケヌスであるため、MochaがuncaughtExceptionず同じようにこれをサポヌトするこずを期埅しおいたす。 Promisesを䜿甚しおいるからずいっお、それを発信者に返したいずいう意味ではありたせん。

[email protected]でも同じ問題があり

    it('Convert files into base64', (resolve) => {
        let files = Promise.all(promises);

        return files
            .then(([actual, expected]) => {
                assert.equal(actual, expected, 'Files not are equal');
                resolve();
            })
            .catch(error => resolve);
    });
   Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

.catchが間違っおいたす。 error => resolveはfunction(error) { return resolve } error => resolveず同等です。぀たり、 resolveは呌び出されず、゚ラヌは無芖されたす。 必芁なのは、゚ラヌ付きでresolveを呌び出すこずです。これは、 error => resolve(error)たす。 もちろん、 Xが呌び出されるのず同じ匕数で関数Yを呌び出すだけのコヌルバック関数Xを枡すこずは、 Yを単に枡すこずず同じです。コヌルバックなので、 .catch(error => resolve(error))でも.catch(resolve)簡略化できたす。  then枡す堎合は、 resolve盎接枡す必芁がないため、 thenの結果パラメヌタヌをresolve枡さないようにする必芁がありたす。゚ラヌずしお扱われないようにするためのthen(()=>resolve())ではなく.then(resolve) ;ただし、アサヌションにthenコヌルバックを䜿甚しおいるため、これは発生したせん。 。

たた、慣䟋的に、ここでのresolveは、成功ず倱敗の䞡方を凊理し、匕数で呌び出されたかどうかに基づいおどちらが呌び出されたかを刀断するため、おそらくdoneに沿った名前を付ける必芁がありたす。したがっお、モカの゚ラヌメッセヌゞにある名前ですが、それは論点かもしれたせん。読み進めおください。

ただし、この堎合、Mochaはテストの成功たたは倱敗を瀺すものずしおpromiseが成功たたは倱敗するのを埅぀ため、promiseを返すだけで、test doneパラメヌタヌをたったく䜿甚しないこずで、さらに単玔化できたすdoneパラメヌタヌがない堎合テスト関数;䞡方が䜿甚された堎合の動䜜はただハッシュ化されおいたす

it('Convert files into base64', () => {
    let files = Promise.all(promises);
    return files
        .then(([actual, expected]) => {
            assert.equal(actual, expected, 'Files not are equal');
        })
});

@lsphillipsは私のために働きたす。 ありがずう mochaがデフォルトでこれをサポヌトするこずを期埅しおいたす。 2640を䜜成したした。

これを解決するのに少し時間がかかりたした 䞊蚘の回答に基づいお、これらは2぀のオプションです。

npm install --save mocha expect.js q
./node_modules/mocha/bin/mocha test.spec.js

// test.spec.js

var $q = require('q');
var expect = require('expect.js');

describe('tests with done', function(){
    it('returns the correct value from promise', function(done) {
      var returnValue = 5;
      var def = $q.defer();
      def.promise.then((val) => {
        expect(val).to.equal(42);
        done();
      }).catch(done);
      def.resolve(returnValue)
    });
})

describe('tests returning promises', function(){
    it('returns the correct value from promise', function() {
      var returnValue = 5;
      var def = $q.defer();
      def.resolve(returnValue)
      return def.promise.then((val) => {
        expect(val).to.equal(42);
      });
    });
})
  tests with done
    1) returns the correct value from promise

  tests returning promises
    2) returns the correct value from promise


  0 passing (15ms)
  2 failing

  1) tests with done returns the correct value from promise:
     Error: expected 5 to equal 42
      at Assertion.assert (node_modules/expect.js/index.js:96:13)
      at Assertion.be.Assertion.equal (node_modules/expect.js/index.js:216:10)
      at def.promise.then (tests/test.spec.js:9:24)
      at _fulfilled (node_modules/q/q.js:854:54)
      at self.promiseDispatch.done (node_modules/q/q.js:883:30)
      at Promise.promise.promiseDispatch (node_modules/q/q.js:816:13)
      at node_modules/q/q.js:570:49
      at runSingle (node_modules/q/q.js:137:13)
      at flush (node_modules/q/q.js:125:13)
      at _combinedTickCallback (internal/process/next_tick.js:67:7)
      at process._tickCallback (internal/process/next_tick.js:98:9)

  2) tests returning promises returns the correct value from promise:
     Error: expected 5 to equal 42
      at Assertion.assert (node_modules/expect.js/index.js:96:13)
      at Assertion.be.Assertion.equal (node_modules/expect.js/index.js:216:10)
      at def.promise.then (tests/test.spec.js:22:24)
      at _fulfilled (node_modules/q/q.js:854:54)
      at self.promiseDispatch.done (node_modules/q/q.js:883:30)
      at Promise.promise.promiseDispatch (node_modules/q/q.js:816:13)
      at node_modules/q/q.js:570:49
      at runSingle (node_modules/q/q.js:137:13)
      at flush (node_modules/q/q.js:125:13)
      at _combinedTickCallback (internal/process/next_tick.js:67:7)
      at process._tickCallback (internal/process/next_tick.js:98:9)

@gurdiga setTimeoutのアむデアをありがずう 同様の問題が発生したしたが、少なくずも適切な゚ラヌメッセヌゞが衚瀺されるようになりたした。

私のシナリオでは、Nightmareを䜿甚しおテストを終了したした。 私にずっおの解決策は、 .catch(done)䜿甚するこずdone(error)を呌び出すこずができたす。

describe('Clicking in any bad reputation tag', () => {
    it('open the bad reputation modal', (done) => {
      nightmare
        .select('#per-page', '50')
        .waitForAjax()
        .click('[data-reputation="bad"]')
        .evaluate(function() {
          return document.querySelector('.vue-modal .ls-modal-title').innerText
        })
        .then(function(title) {
          title.should.equal('Sua segmentação teve uma avaliação ruim!')
          done()
        })
        .catch((error) => {
          screenshot(nightmare)
          done(error)
        })
    })
  })

@itumoraesは機胜したすが、代わりにこれを行うこずができたす

describe('Clicking in any bad reputation tag', () => {
    it('open the bad reputation modal', () => {
      return nightmare
        .select('#per-page', '50')
        .waitForAjax()
        .click('[data-reputation="bad"]')
        .evaluate(function() {
          return document.querySelector('.vue-modal .ls-modal-title').innerText
        })
        .then(function(title) {
          title.should.equal('Sua segmentação teve uma avaliação ruim!')
        })
    })
  })

玄束を返す堎合は、 done()を呌び出す必芁はありたせん。 Mocha、Express、MongooseでのAsync / Awaitの䜿甚に関するブログ投皿

以䞋のスクリプトを䜿甚したしたが、同じタむムアりト超過゚ラヌが発生したした。

Myscript

describe "getBillingDetail"、async function{
this.timeout55000;
it.only "指定された有効なゞョブ名を確認しおください"、async関数完了{
this.timeout55000;
var result = await url.getBillingDetail '12254785565647858';
console.logresult;
assert.equalresult、true;
};
};

゚ラヌ55000msのタむムアりトを超えたした。 非同期テストずフックの堎合は、「done」が呌び出されおいるこずを確認しおください。 Promiseを返す堎合は、それが解決されるこずを確認しおください。

耇数のクロヌズされた問題で同じこずを綎るのをやめたす。 完了したコヌルバックを非同期関数に枡さないでください。 非同期テストに関するドキュメントを読む

@Munter完了したコヌルバックを削陀したしたが、これらの゚ラヌが再び発生したす

あなたの玄束は決しお解決されなかったようです。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡