在我的项目中,我有一个非常复杂的选择器结构(一些选择器可能有多达5层的嵌套),所以其中一些很难通过输入状态进行测试,我想模拟输入选择器。然而,我发现这是不可能的。
下面是最简单的例子:
// selectors1.js
export const baseSelector = createSelector(...);
字符串
// selectors2.js
export const targetSelector = createSelector([selectors1.baseSelector], () => {...});
型
我希望在我的测试套件中有:
beforeEach(() => {
jest.spyOn(selectors1, 'baseSelector').mockReturnValue('some value');
});
test('My test', () => {
expect(selectors2.targetSelector()).toEqual('some value');
});
型
但是,这种方法不起作用,因为targetSelector
在selectors2.js
初始化期间引用selectors1.baseSelector
,然后mock被分配给selectors1.baseSelector
。
我现在看到的两个解决方案是:
1.用jest.mock
模拟整个selectors1.js
模块,但是,如果我需要在某些特定情况下更改selectors1.baseSelector
输出,那么它将不起作用
1.像这样 Package 每个依赖选择器:
export const targetSelector = createSelector([(state) => selectors1.baseSelector(state)], () => {...});
型
但我不太喜欢这种方法,原因很明显。
所以,接下来的问题是:有没有机会在单元测试中正确地模拟Reselect选择器?
5条答案
按热度按时间hrysbysz1#
对于任何试图使用Typescript解决这个问题的人来说,这篇文章最终对我有效:https://dev.to/terabaud/testing-with-jest-and-typescript-the-tricky-parts-1gnc
我的问题是,我正在测试一个模块,在创建请求的过程中调用了几个不同的选择器,而我创建的
redux-mock-store
状态在测试执行时对选择器不可见。我最终跳过了mock store,而是模仿了被调用的特定选择器的返回数据。过程是这样的:
字符串
.mockImplementation
沿着ts-jest\utils
中的mocked
帮助器,它允许您 Package 每个选择器并为每个选择器给予自定义返回数据。型
test()
定义中这样做:型
oknwwptz2#
除了@nate-peters的回答,我想分享一个更简单的版本:
字符串
然后在每个
it(...)
块中,您可以实现型
piztneat3#
我也遇到了同样的问题。我最终用
jest.mock
模拟了reselect createSelector
,在测试时忽略了除了最后一个参数(这是你想要测试的核心函数)之外的所有参数。总的来说,这种方法对我很有用。我遇到的问题
我的选择器模块中有一个循环依赖。我们的代码库太大了,我们没有足够的带宽来相应地重构它们。
为什么我使用这种方法?
我们的代码库在选择器中有很多循环依赖。试图重写和重构它们以消除循环依赖是太多的工作。因此,我选择了mock
createSelector
,这样我就不必花时间重构。如果您的选择器代码库是干净的,没有依赖性,那么一定要考虑使用
reselect
resultFunc
。更多文档请访问:https://github.com/reduxjs/reselect#createselectorinputselectors--inputselectors-resultfunc我用来嘲笑
createSelector
的代码字符串
然后访问创建的选择器,我有这样的东西
型
整个测试套件代码运行
型
ao218c7q4#
Reselect是基于组合概念的。所以你从许多其他选择器中创建了一个选择器。你真正需要测试的不是整个选择器,而是完成这项工作的最后一个函数。如果不是,测试将彼此重复,就好像你有selector1的测试,selector1在selector2中使用,然后你自动在selector2测试中测试它们。
为了实现:
只测试选择器的结果函数。它可以通过
selector.resultFunc
访问。例如:
字符串
摘要
我们没有测试整个组合,也没有重复相同的Assert,或者模拟特定的选择器输出,而是测试定义选择器的函数,因此,选择器中的最后一个参数,可以通过
resultFunc
键访问。uklbhaso5#
您可以通过模拟整个
selectors1.js
模块来实现这一点,但也可以在测试内部导入,以便访问模拟的功能假设您的
selectors1.js
看起来像字符串
selectors2.js
看起来像型
然后你可以写一些测试,比如
型
jest.mock
函数调用将被提升到模块的顶部以模拟selectors1.js
模块当您执行import
/require
selectors1.js
时,您将获得baseSelector
的模拟版本,您可以在运行测试之前控制其行为