React 和 jest 模拟模块
React and jest mock module
我正在创建一个应用程序,我在其中使用 redux 和 node-fetch 进行远程数据获取。
我想测试一下我是否使用正确的参数调用 fetch 函数。
这样,我正在使用 jest.mock 和 jasmine.createSpy 方法:
it('should have called the fetch method with URL constant', () => {
const spy = jasmine.createSpy('nodeFetch');
spy.and.callFake(() => new Promise(resolve => resolve('null')));
const mock = jest.mock('node-fetch', spy);
const slug = 'slug';
actionHandler[FETCH_REMOTE](slug);
expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
});
这是我要测试的功能:
[FETCH_REMOTE]: slug => {
return async dispatch => {
dispatch(loading());
console.log(fetch()); // Displays the default fetch promise result
await fetch(Constants.URL + slug);
addLocal();
};
}
如您所见,我正在尝试记录 console.log(fetch()) 行为,并且我有默认承诺来解决节点获取给出的问题,而不是我已经用 Jest 模拟,用 jasmine 监视。
你知道它不起作用吗?
编辑:我的测试向我显示了一个错误,就像我的间谍从未被调用过
您的操作处理程序实际上是一个操作处理程序工厂。在 actionHandler[FETCH_REMOTE]
中,您正在创建一个新函数。返回的函数任务 dispatch
作为参数并调用您显示的代码。
这意味着您的测试代码永远不会调用间谍上的任何函数,因为永远不会调用创建的函数。
我认为您需要创建一个模拟 dispatch
函数并执行如下操作:
let dispatchMock = jest.fn(); // create a mock function
actionHandler[FETCH_REMOTE](slug)(dispatchMock);
编辑:
对我来说,你的 actionHandler
看起来更像是一个 actionCreator
,因为它通常在 redux 术语中被称为,尽管我个人更喜欢称它们为 actionFactories
因为它们就是这样是:创建动作的工厂。
当您使用 thunks
(?) 时,您的 actionCreater
(误命名为 actionHandler
)不会直接创建 action
,而是会在操作后立即调用另一个函数被派遣。作为比较,常规的 actionCreator 看起来像这样:
updateFilter: (filter) => ({type: actionNames.UPDATE_FILTER, payload: {filter: filter}}),
A actionHandler
另一方面对正在调度的动作做出反应并评估它们的有效负载。
针对您的情况,我会这样做:
像这样创建一个名为 actionFactories
的新对象:
const actionFactories = {
fetchRemote(slug): (slug) => {
return async dispatch => {
dispatch(loading());
console.log(fetch()); // Displays the default fetch promise result
let response = await fetch(Constants.URL + slug);
var responseAction;
if (/* determine success of response */) {
responseAction = actionFactories.fetchSuccessful(response);
} else {
responseAction = actionFactories.fetchFailed();
}
dispatch(responseAction);
};
}
fetchFailed(): () => ({type: FETCH_FAILED, }),
fetchSuccessful(response): () => ({type: FETCH_FAILED, payload: response })
};
为 FETCH_FAILED
和 FETCH_SUCCESSFUL
创建 actionHandler 以根据响应更新商店。
顺便说一句:你的 console.log
声明对我来说也没有多大意义,因为 fetch
只是 returns 一个承诺。
我正在创建一个应用程序,我在其中使用 redux 和 node-fetch 进行远程数据获取。
我想测试一下我是否使用正确的参数调用 fetch 函数。
这样,我正在使用 jest.mock 和 jasmine.createSpy 方法:
it('should have called the fetch method with URL constant', () => {
const spy = jasmine.createSpy('nodeFetch');
spy.and.callFake(() => new Promise(resolve => resolve('null')));
const mock = jest.mock('node-fetch', spy);
const slug = 'slug';
actionHandler[FETCH_REMOTE](slug);
expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
});
这是我要测试的功能:
[FETCH_REMOTE]: slug => {
return async dispatch => {
dispatch(loading());
console.log(fetch()); // Displays the default fetch promise result
await fetch(Constants.URL + slug);
addLocal();
};
}
如您所见,我正在尝试记录 console.log(fetch()) 行为,并且我有默认承诺来解决节点获取给出的问题,而不是我已经用 Jest 模拟,用 jasmine 监视。
你知道它不起作用吗?
编辑:我的测试向我显示了一个错误,就像我的间谍从未被调用过
您的操作处理程序实际上是一个操作处理程序工厂。在 actionHandler[FETCH_REMOTE]
中,您正在创建一个新函数。返回的函数任务 dispatch
作为参数并调用您显示的代码。
这意味着您的测试代码永远不会调用间谍上的任何函数,因为永远不会调用创建的函数。
我认为您需要创建一个模拟 dispatch
函数并执行如下操作:
let dispatchMock = jest.fn(); // create a mock function
actionHandler[FETCH_REMOTE](slug)(dispatchMock);
编辑:
对我来说,你的 actionHandler
看起来更像是一个 actionCreator
,因为它通常在 redux 术语中被称为,尽管我个人更喜欢称它们为 actionFactories
因为它们就是这样是:创建动作的工厂。
当您使用 thunks
(?) 时,您的 actionCreater
(误命名为 actionHandler
)不会直接创建 action
,而是会在操作后立即调用另一个函数被派遣。作为比较,常规的 actionCreator 看起来像这样:
updateFilter: (filter) => ({type: actionNames.UPDATE_FILTER, payload: {filter: filter}}),
A actionHandler
另一方面对正在调度的动作做出反应并评估它们的有效负载。
针对您的情况,我会这样做:
像这样创建一个名为 actionFactories
的新对象:
const actionFactories = {
fetchRemote(slug): (slug) => {
return async dispatch => {
dispatch(loading());
console.log(fetch()); // Displays the default fetch promise result
let response = await fetch(Constants.URL + slug);
var responseAction;
if (/* determine success of response */) {
responseAction = actionFactories.fetchSuccessful(response);
} else {
responseAction = actionFactories.fetchFailed();
}
dispatch(responseAction);
};
}
fetchFailed(): () => ({type: FETCH_FAILED, }),
fetchSuccessful(response): () => ({type: FETCH_FAILED, payload: response })
};
为 FETCH_FAILED
和 FETCH_SUCCESSFUL
创建 actionHandler 以根据响应更新商店。
顺便说一句:你的 console.log
声明对我来说也没有多大意义,因为 fetch
只是 returns 一个承诺。