用 Jest 模拟基于承诺的请求
Posted
技术标签:
【中文标题】用 Jest 模拟基于承诺的请求【英文标题】:Mocking promised based request with Jest 【发布时间】:2017-02-26 01:48:59 【问题描述】:我正在尝试使用 Jest 对函数进行单元测试,但在处理 jest 模拟模块(相当于 nodejs 世界中的 rewire 或 proxyquire)时遇到了一些麻烦。
我实际上是在尝试使用一些参数在模拟模块上调用间谍。这是我要测试的功能。
注意:当前测试只涉及“fetch(...)”部分,我正在尝试测试是否使用 good 参数调用了 fetch。
export const fetchRemote = slug =>
return dispatch =>
dispatch(loading());
return fetch(Constants.URL + slug)
.then(res => res.json())
.then(cmp =>
if (cmp.length === 1)
return dispatch(setCurrent(cmp[0]));
return dispatch(computeRemote(cmp));
);
;
;
返回的函数充当闭包,因此“捕获”了我要模拟的节点获取外部模块。
这是我试图通过绿色的测试:
it('should have called the fetch function wih the good const parameter and slug', done =>
const slug = 'slug';
const spy = jasmine.createSpy();
const stubDispatch = () => Promise.resolve(json: () => []);
jest.mock('node-fetch', () => spy);
const dispatcher = fetchRemote(slug);
dispatcher(stubDispatch).then(() =>
expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
done();
);
);
编辑:第一个答案对编写测试有很大帮助,我现在有以下一个:
it('should have called the fetch function wih the good const parameter and slug', done =>
const slug = 'slug';
const stubDispatch = () => null;
const spy = jest.mock('node-fetch', () => Promise.resolve(json: () => []));
const dispatcher = fetchRemote(slug);
dispatcher(stubDispatch).then(() =>
expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
done();
);
);
但是现在,这是我遇到的错误:
console.error node_modules/core-js/modules/es6.promise.js:117
Unhandled promise rejection [Error: expect(jest.fn())[.not].toHaveBeenCalledWith()
jest.fn() value must be a mock function or spy.
Received:
object: "addMatchers": [Function anonymous], "autoMockOff": [Function anonymous], "autoMockOn": [Function anonymous], "clearAllMocks": [Function anonymous], "clearAllTimers": [Function anonymous], "deepUnmock": [Function anonymous], "disableAutomock": [Function anonymous], "doMock": [Function anonymous], "dontMock": [Function anonymous], "enableAutomock": [Function anonymous], "fn": [Function anonymous], "genMockFn": [Function bound getMockFunction], "genMockFromModule": [Function anonymous], "genMockFunction": [Function bound getMockFunction], "isMockFunction": [Function isMockFunction], "mock": [Function anonymous], "resetModuleRegistry": [Function anonymous], "resetModules": [Function anonymous], "runAllImmediates": [Function anonymous], "runAllTicks": [Function anonymous], "runAllTimers": [Function anonymous], "runOnlyPendingTimers": [Function anonymous], "runTimersToTime": [Function anonymous], "setMock": [Function anonymous], "unmock": [Function anonymous], "useFakeTimers": [Function anonymous], "useRealTimers": [Function anonymous]]
【问题讨论】:
【参考方案1】:首先你需要在testing async code时返回一个promise。你的间谍需要返回一个已解决或被拒绝的承诺。
it('should have called the fetch function wih the good const parameter and slug', done =>
const slug = 'successPath';
const stubDispatch = () => Promise.resolve( json: () => [] );
spy = jest.mock('node-fetch', (path) =>
if (path === Constants.URL + 'successPath')
return Promise.resolve('someSuccessData ')
else
return Promise.reject('someErrorData')
);
const dispatcher = fetchRemote(slug);
return dispatcher(stubDispatch).then(() =>
expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
done();
);
);
【讨论】:
我在这个实现中看不到间谍:/。不过谢谢你的回答 你试过expect(spy.mock)
而不是expect(spy)
吗?
你必须从你的测试中返回调度员。
我试过了,但没办法。似乎节点模块根本没有被嘲笑。当我在没有后端的情况下运行测试时,它会发送请求并抛出错误
好的,那么如何将fetch
导入到您的模块中,还是使用原生JS 实现?以上是关于用 Jest 模拟基于承诺的请求的主要内容,如果未能解决你的问题,请参考以下文章