2016-11-21 109 views
1

我正在使用Typescript,使用Mocha並嘗試使用ES6 async/await生成器。使用Typescript異步的摩卡API測試

這裏是我的代碼:

"use strict"; 
import * as console from 'console'; 
import { Config } from './Config'; 
import * as assert from 'assert'; 
import * as mocha from 'mocha'; 
import fetch from 'node-fetch'; 

async function createExchangeRate(date: string) { 
    let body = JSON.stringify({ 
    'ts': date, 
    'gbptoUSD': 1.0, 
    'eurtoUSD': 1.0, 
    'cyntoUSD': 1.0 
    }); 
    return fetch(`${Config.host()}/exchangeRate`, { method: 'POST', body: body }); 
} 

describe('/exchangeRate', function() { 

    let date = '2016-01-01'; 

    it('creates the exchange rate', async function(done) { 
    let response = await createExchangeRate(date); 
    console.log('Got my promise!'); 
    let body = await response.json(); 
    assert.equal(response.status, 204); 
    assert.ok(body.uuid); 
    done(); 
    }); 

}); 

一切正確編譯但通過createExchangeRate返回的承諾似乎從來沒有得到解決,並且永遠不會達到console.log

最終摩卡測試時間了,我得到類似的消息:

Error: timeout of 5000ms exceeded. Ensure the done() callback is being called in this test.

我已經嘗試了各種不同的格式,但不能看到我要去哪裏錯了...

UPDATE

如果我修改我的測試,以除去異步/等待關鍵字,它的工作原理:

it('creates the exchange rate',() => { 
    createExchangeRate(date).then(function(response) { 
    expect(response.status).to.equal(204); 
    response.json().then(function(body) { 
     expect(body.uuid).to.be.ok; 
    }); 
    }); 
}); 
+1

你是否試過在Mocha之外將測試代碼作爲普通函數運行? *如果*您可以在沒有摩卡的情況下複製相同的行爲,那非常有用。首先,您可以將注意力集中在問題實際存在的位置(而不是Mocha)。其次,你可以在這裏重寫你的問題,以消除摩卡,這將有助於讓更多讀者閱讀你的問題。人們傾向於跳過標有他們不知道的技術的問題。問題標籤越多,潛在讀者的集合越小。 – Louis

+0

您的函數createExchangeRate可能比默認超時多嗎?請記住,超時也包含初始化代碼(因此它不僅僅是您的代碼執行)。首先,你可以在'await'代碼前加'this.timeout = someValue'來嘗試增加超時。 – SzybkiSasza

+0

我試着添加30秒的超時,但不幸的是沒有任何區別。 – timothyclifford

回答

1

createExchangeRate上的async是沒有必要的(雖然我不認爲它真的很痛)。 async關鍵字允許你使用await(你不知道)並且讓你的函數返回一個承諾(當你返回fetch()時你已經在做這個承諾)。

此外,重構後的額外測試不起作用!它執行一些異步操作,但不等待響應。摩卡對這個承諾一無所知,除非你告訴它,否則只要createExchangeRate返回(即在請求返回之前立即返回),Mocha認爲你的測試是成功的。如果你在每個階段回覆承諾(return createExchangeRate(...return response.json(...),那麼它會做你的期望。

更重要的是,你正在混合兩種方式處理摩卡異步,done和承諾。如果你添加一個完成的參數,Mocha等到你調用它。如果你回覆承諾,摩卡就會等待,直到承諾解決。你只想做其中的一個,我認爲試圖做這兩件事情在這裏引起你的一些問題是合理的。

如果你沒有包含done參數,並且你的測試返回一個promise(就像異步函數自動執行的那樣),所有的東西都可能工作。就個人而言,我會把你的測試寫成:

describe('/exchangeRate', function() { 
    let date = '2016-01-01'; 

    it('creates the exchange rate', async function() { 
    let response = await createExchangeRate(date); 
    console.log('Got my promise!'); 
    let body = await response.json(); 
    assert.equal(response.status, 204); 
    assert.ok(body.uuid); 
    }); 
}); 
1

您的功能createExchangeRate裏面沒有await關鍵字。因此,該功能不是async。刪除async之前的關鍵字,它應該工作正常。