我遇到使用fetch的存根/测试功能的问题。
使用简单的例子:
export const clickTimeseries => {
return fetch('...url...')
.then(response => {
if(response.status == 200)
return response.json()
else
throw 'something'
})
.then(json => {
return {
success: true,
data: json,
}
})
.catch(err => {
return {
success: false,
error: err,
}
})
}
我的测试:
import { expect } from 'chai'
import sinon from 'sinon'
import Promise from 'es6-promise'
Promise.polyfill()
import 'whatwg-fetch'
import clickTimeseries from './above'
const jsonOK = body => {
const mockResponse = new Response(JSON.stringify(body), {
status: 200,
headers: {
'Content-type': 'application/json'
}
})
return Promise.resolve(mockResponse)
}
describe('APIs', () => {
describe('Click timeseries', () => {
it('builds a correct data on success', () => {
sinon.stub(window, 'fetch').returns(jsonOK({stuff: [1,2,3]}))
expect(clickTimeseries()).to.eq({
success: true,
data: {stuff: [1,2,3]}
})
})
})
})
我收到错误:
expected { Object (, _state, ...) } to equal { success: true, data: {stuff: [ 1, 2, 3, 4 ] }}
看起来spendTimeseries
会返回promise,而不是调用then
块的结果。
您如何设置测试以使其通过?
答案 0 :(得分:3)
我花了一些时间玩你的代码,直到我意识到错误,因为一切看起来都是正确的。事实上,确实如此。除了一件事:您正在测试的结果是异步传递的,但您正在同步测试它。这意味着您需要将测试更改为异步。
我假设您使用Mocha作为测试运行器,它有两种测试异步代码的方法。任何异步代码的一种标准方法,以及一种处理Promise的特殊方法。你可以使用适合你风格的任何东西。
如果您有任何异步代码,以后会传递结果,这是一般公式:
it('should test an async function', (callback) => {
const expectedResult = 42;
doSomethingAsync((result) => {
try{
expect(expectedResult).to.equal(result);
callback();
} catch(err) {
callback(err);
}
})
});
对于承诺返回函数,这将是这样的:
it('should test a promise', (callback) => {
const expectedResult = 42;
doSomethingAsync().then((result) => {
expect(expectedResult).to.equal(result);
callback();
}).catch(callback);
});
Mocha有一些承诺的糖,可以像这样编写最后一个函数(在函数包装器中没有回调!):
it('should test a promise', () => {
const expectedResult = 42;
return doSomethingAsync().then((result) => {
expect(expectedResult).to.equal(result);
})
});
总之:只需将测试改为:
return clickTimeseries().then( result => {
expect(result).to.eq({
success: true,
data: {stuff: [1,2,3]}
})
})