我对Jest还是个新手,而且我承认我不是测试异步代码的Maven...
我使用了一个简单的Fetch
助手:
export function fetchHelper(url, opts) {
return fetch(url, options)
.then((response) => {
if (response.ok) {
return Promise.resolve(response);
}
const error = new Error(response.statusText || response.status);
error.response = response;
return Promise.reject(error);
});
}
并像这样实现它:
export function getSomeData() {
return (dispatch) => {
return fetchHelper('http://datasource.com/').then((res) => {
dispatch(setLoading(true));
return res.json();
}).then((data) => {
dispatch(setData(data));
dispatch(setLoading(false));
}).catch(() => {
dispatch(setFail());
dispatch(setLoading(false));
});
};
}
但是,我希望测试是否在正确的环境中以正确的顺序触发了正确的分派。
这在sinon.spy()
中曾经非常容易,但是我不知道如何在Jest中复制它。理想情况下,我希望我的测试看起来像这样:
expect(spy.args[0][0]).toBe({
type: SET_LOADING_STATE,
value: true,
});
expect(spy.args[1][0]).toBe({
type: SET_DATA,
value: {...},
});
提前感谢您的任何帮助或建议!
5条答案
按热度按时间5t7ly7z51#
截至2018年1月的答复
redux文档中有一篇关于测试异步操作创建者的文章 *:
对于使用Redux Thunk或其他中间件的异步操作创建者,最好完全模拟Redux存储进行测试。您可以使用redux-mock-store将中间件应用于模拟存储。您还可以使用fetch-mock模拟HTTP请求。
他们的方法不是使用jest(或sinon)进行间谍活动,而是使用模拟存储并Assert调度的操作。这样做的好处是能够处理thunk调度thunk,而这对于间谍活动来说可能非常困难。
这些都是直接从文档中得到的,但是如果你想让我为你的thunk创建一个例子,请告诉我。
ugmeyewa2#
截至2018年1月的答复
对于使用Redux Thunk或其他中间件的异步操作创建者,最好完全模拟Redux存储进行测试。您可以使用
redux-mock-store
将中间件应用于模拟存储。为了模拟HTTP请求,您可以使用nock
。根据
redux-mock-store
documentation,您需要在请求结束时调用store.getActions()
来测试异步操作,您可以将测试配置为mockStore(getState?: Object,Function) => store: Function
返回已配置模拟存储的示例。如果您希望在每次测试后重置存储,则应调用此函数。store.dispatch(action) => action
通过模拟存储调度操作。该操作将存储在示例内的数组中并执行。store.getState() => state: Object
返回模拟存储的状态store.getActions() => actions: Array
返回模拟存储的操作store.clearActions()
清除存储的操作您可以将测试操作编写为
然后将
mockStore
配置为希望它能有所帮助。另外,请在redux文档中检查this关于测试异步操作创建者的内容
uubf1zoe3#
如果要使用
jest.fn()
模拟dispatch函数,只需访问dispatch.mock.calls
即可获取对存根的所有调用。h5qlskok4#
在我的回答中,我使用
axios
而不是fetch
,因为我在获取承诺方面没有太多经验,这对你的问题应该没有关系。请看下面我提供的代码示例:
这里我模拟了获取助手返回Resolved promise到测试成功部分,并拒绝promise到测试失败的API调用。你也可以向它们传递参数来验证响应。
可以像这样实现
getSomeData
:我希望这能解决你的问题。如果你需要任何澄清,请发表评论。
你可以通过查看上面的代码看到为什么我更喜欢axios而不是fetch,这可以让你避免很多承诺解析!
如需进一步阅读,请参阅:https://medium.com/@thejasonfile/fetch-vs-axios-js-for-making-http-requests-2b261cdd3af5
u7up0aaq5#
截至2023年1月的相关答案
2018年的许多有用的答案现在已经过时了,2023年的答案是避免嘲笑商店,而是使用真实的的商店,更喜欢集成测试(仍然使用jest)而不是单元测试。
更新后的official Redux testing documentation中的一些亮点:
喜欢编写集成测试,让所有东西都协同工作。对于使用Redux的React应用,使用真实的的商店示例渲染 Package 被测组件。与被测页面的交互应使用真实的Redux逻辑,模拟API调用,以便应用代码不必更改,并AssertUI已适当更新。
不要尝试模拟选择器函数或React-Redux钩子!模拟从库导入是脆弱的,并且不能给予您确信实际的应用代码正在工作。
它继续说明如何实现这一点,并在这里详细介绍
renderWithProvider
函数。The article it links to for reasoning on this,包括以下引文,解释了redux测试最佳实践思想的演变:
我们的医生一直在教授“隔离”方法,这对简化者和选择者来说尤其有意义,而“整合”方法则是少数。
但是,RTL和肯特C Dodds彻底改变了React生态系统中的测试思维和方法,我现在看到的模式是关于“集成”风格的测试--大块代码一起工作,就像它们在真实的应用中使用的那样。