javascript - 有没有办法正确模拟单元测试的重新选择选择器?
问题描述
我的项目中有一个非常复杂的选择器结构(一些选择器可能有多达 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
获取引用那样工作,并且在它之后分配模拟。selectors1.baseSelector
selectors2.js
selectors1.baseSelector
我现在看到了 2 个可行的解决方案:
- 用模拟整个
selectors1.js
模块jest.mock
,但是,如果我需要selectors1.baseSelector
为某些特定情况更改输出,它将不起作用 - 像这样包装每个依赖项选择器:
export const targetSelector = createSelector([(state) => selectors1.baseSelector(state)], () => {...});
但出于显而易见的原因,我不太喜欢这种方法。
那么,接下来的问题是:是否有机会正确地模拟 Reselect 选择器以进行单元测试?
解决方案
问题是 Reselect 是基于组合概念的。因此,您从许多其他选择器中创建了一个选择器。您真正需要测试的不是整个选择器,而是完成这项工作的最后一个函数。如果不是,测试将相互重复,就好像您对选择器 1 进行了测试,并且选择器 1 用于选择器 2,然后您自动在选择器 2 测试中测试它们。
为了要达到:
- 少嘲讽
- 无需专门模拟组合选择器的结果
- 没有重复测试
只测试选择器的结果函数。它可以通过 访问selector.resultFunc
。
例如:
const selector2 = createSelector(selector1, (data) => ...);
// tests
const actual = selector2.resultFunc([returnOfSelector1Mock]);
const expected = [what we expect];
expect(actual).toEqual(expected)
概括
我们不是测试整个组合、复制相同的断言或模拟特定的选择器输出,而是测试定义选择器的函数,因此 createSelector 中的最后一个参数可以通过resultFunc
键访问。
推荐阅读
- excel - 如何在vba中动态更改链接名称?
- rx-java2 - 使用 flatMapSingle 时如何避免多次映射器调用
- java - 为什么排序方法不适用于arraylist对象
- javascript - 延迟 Javascript 函数,直到数据加载
- azure - How to keep folder structure in blob storage when using Data Factory to copy file
- python - 如何在 PyCharm 中创建一个没有文件名/路径的空文件?
- javascript - 如何使用 Barba.js 实现 Facebook 分析
- c++ - 我无法从 max_element() 中获得所需的输出
- powershell - 如何测试具有特定值的注册表项是否存在而不给出错误消息
- xpath - XPATH - 如果找到某个类,则在 div 中获取 URL