2017-08-02 93 views
4

我很努力地找出驗證承諾在使用異步/等待時在Mocha測試中被拒絕的最佳方法。驗證使用Mocha/Chai和異步/等待引發異常

以下是一個可行的示例,但我不喜歡should.be.rejectedWith返回需要從測試函數返回以便正確評估的承諾。使用async/await可以刪除測試值的這個要求(正如我對下面wins()的結果所做的那樣),並且我覺得在某些時候我很可能會忘記返回語句,在這種情況下測試總是會通過。

// 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'); 
}); 

感覺像它應該是能夠使用異步/ AWAIT轉化拒絕例外的事實,並結合起來,與柴氏should.throw,但我一直沒能確定正確的語法。

理想情況下這會工作,但似乎並不:

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

我試過了,但是await必須封裝在一個異步函數中 - 它本身那麼需要等待。 D'哦! – plexer

回答

0

的問題,這種做法是(await fails()).should.throw(Error)沒有意義。

await解決了Promise。如果Promise拒絕,則拋出拒絕值。

所以(await fails()).should.throw(Error)永遠不會工作:如果fails()拒絕,錯誤拋出,並且.should.throw(Error)永遠不會執行。

您擁有的最習慣的選擇是使用Chai的rejectedWith屬性,如您在問題中所示。

下面是一個簡單的例子。與你在你的問題中所展示的沒什麼不同。我只是使用async函數的wins()fails()expect而不是should。當然,您可以使用返回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版或catch版。因此,Mocha認爲沒有任何失敗,並將測試標記爲已通過,但Node.js(如上所述將在未來改變的行爲)將未處理的拒絕打印到終端。