如何为每个测试模拟不同的 useLocation 值?
Posted
技术标签:
【中文标题】如何为每个测试模拟不同的 useLocation 值?【英文标题】:How to mock different value, of useLocation, for each test? 【发布时间】:2020-08-10 00:07:06 【问题描述】:我的 react 组件应该根据当前位置对状态进行一些更改。
有自定义钩子,在组件加载时调用。
在钩子中有一个useLocation().pathname
的检查和正确更改的开关/大小写结果。
这可以在一个文件/描述中进行 Jest 测试吗?
我试过jest.mock
useLocation
,但我无法在 Jest describe 中做到这一点......
这是模拟,目前不在描述中 - 这有效,但不能在测试之间更改:
const mockUseLocation = () =>
jest.mock('react-router-dom', () => (
useLocation: jest.fn().mockReturnValue(
pathname: '/val1'
)
))
;
如何测试所有的 switch/case 分支?
switch (pathname)
case 'val1':
return 100;
case 'val2':
return 200;
...
...
【问题讨论】:
【参考方案1】:最简单的方法是使用MemoryRouter
而不是模拟useLocation
。如果你的组件有<Link>
,这也会很有帮助(否则你会得到错误“链接不能在路由器之外使用”)。它还允许您检查导航是否发生。所以这么多好处直接嘲笑useLocation
没有任何价值。
在官方文档中使用look into examples。应该是一样的:
test("current user is active in sidebar", () =>
const wrapper = mount(
<MemoryRouter initialEntries=["/users/2"]>
<YourComp />
</MemoryRouter>
);
expected(wrapper.find(User)).toHaveLength(2);
);
【讨论】:
【参考方案2】:为了摆脱@skyboyer 的回答,我使用renderHook
得到了很好的效果
第一个参数是您要测试的钩子,第二个参数是您的包装器,我将 <MemoryRouter>
、<Route>
包装在 children
道具周围。
// test.js
import React, FC from 'react';
import MemoryRouter, Route from 'react-router-dom';
import renderHook from '@testing-library/react-hooks';
it('returns value from url query', () =>
const wrapper: FC = ( children ) => (
<MemoryRouter initialEntries=[`/?user=authorized`]>
<Route path="*" />
children
</MemoryRouter>
);
const result = renderHook(() => useLocation(), wrapper );
expect(result.current).toBe('authorized');
);
【讨论】:
以上是关于如何为每个测试模拟不同的 useLocation 值?的主要内容,如果未能解决你的问题,请参考以下文章
Azure DevOps:如何为不同的测试(.net core、angular)合并两个代码覆盖率报告
如何为 Android Studio 创建小米模拟器?或者任何其他方式在小米模拟器上测试应用程序?