2017-08-02 27 views
4

async/awaitを使用している間、Mochaテストで約束が拒絶されたかどうかを検証するのに苦労します。Mocha/Chaiとasync/awaitを使用して例外がスローされることを確認してください。

ここでは動作する例がありますが、私は嫌いです。should.be.rejectedWithは、正しく評価されるためにテスト関数から返される必要がある約束を返します。 async/awaitを使用すると、値をテストするためのこの要件が削除されます(これは、後でwins()の結果と同じです)。ある時点でreturn文を忘れる可能性があると感じます。

// Always succeeds 
function wins() { 
    return new Promise(function(resolve, reject) { 
    resolve('Winner'); 
    }); 
} 

// Always fails with an error 
function fails() { 
    return new Promise(function(resolve, reject) { 
    reject('Contrived Error'); 
    }); 
} 

it('throws an error', async() => { 
    let r = await wins(); 
    r.should.equal('Winner'); 

    return fails().should.be.rejectedWith('Contrived Error'); 
}); 

/が待って非同期例外に拒否を変換し、チャイのshould.throwとそれを組み合わせることが、私は正しい構文を決定することができていないという事実を使用することが可能でなければなりませんようにそれは感じています。

理想的には、これは動作しますが、それには思えない。このアプローチの問題は(await fails()).should.throw(Error)は意味がないということである

it('throws an error', async() => { 
    let r = await wins(); 
    r.should.equal('Winner'); 

    (await fails()).should.throw(Error); 
}); 
+0

あなたのテストで 'await fails()'をカプセル化し、この関数に 'should.throw'を適用しようとしてください。 – Troopers

+0

私はこれを試しましたが、待っているのは非同期関数それから待つ必要があります。ああ! – plexer

答えて

0

awaitは、Promiseを解決します。 Promiseが拒否した場合、拒否された値がスローされます。

したがって(await fails()).should.throw(Error)は動作しません。fails()が拒否した場合、エラーがスローされ、.should.throw(Error)は実行されません。

質問に表示されているように、チャイのrejectedWithプロパティを使用するのが最も慣用的なオプションです。

ここに簡単な例があります。あなたの質問であなたが実証したものとあまり違いはありません。私はちょうどwins()asyncshouldの代わりにfails()expectの関数を使用しています。もちろん、Promisechai.shouldを返す関数を使用することもできます。

const chai = require('chai') 
const expect = chai.expect 
chai.use(require('chai-as-promised')) 

// Always succeeds 
async function wins() { 
    return 'Winner' 
} 

// Always fails with an error 
async function fails() { 
    throw new Error('Contrived Error') 
} 

it('wins() returns Winner', async() => { 
    expect(await wins()).to.equal('Winner') 
}) 

it('fails() throws Error', async() => { 
    await expect(fails()).to.be.rejectedWith(Error) 
}) 

あなたが好きなあなたwins()テストがより密接にあなたのfails()テストに似ているしたい場合は、そのようなあなたのwins()テストを書くことができます。

it('wins() returns Winner', async() => { 
    await expect(wins()).to.eventually.equal('Winner') 
}) 

これらの例のいずれかに覚えておくべき重要なことchai-as-promisedは、rejectedWitheventually.somethingのような関数の約束を返します。したがって、あなたはasyncテスト関数のコンテキストでそれらをawaitしなければならないか、あるいは失敗条件がまだ通過します:

async function wins() { 
    return 'Loser' 
} 

async function fails() { 
    return 'Winner' 
} 

it('wins() returns Winner', async() => { 
    expect(wins()).to.eventually.equal('Winner') 
}) 

it('fails() throws Error', async() => { 
    expect(fails()).to.be.rejectedWith(Error) 
}) 

あなたは上記のコードでテストを実行した場合、次の取得したい:

$ npm test 

> [email protected] test /home/vsimonian/code/mocha-chai-async 
> mocha . 



    √ wins() returns Winner 
(node:13836) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rej 
ection id: 1): AssertionError: expected 'Loser' to equal 'Winner' 
(node:13836) [DEP0018] DeprecationWarning: Unhandled promise rejections are dep 
recated. In the future, promise rejections that are not handled will terminate 
the Node.js process with a non-zero exit code. 
    √ fails() throws Error 
(node:13836) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rej 
ection id: 2): AssertionError: expected promise to be rejected with 'Error' but 
it was fulfilled with 'Winner' 

    2 passing (11ms) 

ご覧のとおり、チャイアサーションは実際には失敗しましたが、プロンプトの文脈では失敗しました。await edまたはcatch ed。だから、Mochaは何の失敗も見ず、渡されたかのようにテストに印をつけますが、Node.js(上記のように将来変更される動作で)は未処理の拒否を端末に出力します。

関連する問題