在我们的 JavaScript 开发团队中,我们采用了编写纯函数式代码的 redux/react 风格。然而,我们似乎在对我们的代码进行单元测试时遇到了麻烦。考虑以下示例:
function foo(data) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
此函数调用取决于对和的调用process
,其中每个函数都可以调用其他函数。总之,它们可能需要一个非平凡的模拟 参数来构建测试。extractBar
extractBaz
data
如果我们接受制作这样一个模拟对象的必要性并在测试中实际这样做,我们很快就会发现我们有难以阅读和维护的测试用例。此外,它很可能会导致反复测试相同的东西,就像对 , 的单元测试一样process
,extractBar
并且extractBaz
可能也应该编写。通过 tofoo
接口对这些函数实现的每个可能的边缘情况进行测试是很麻烦的。
我们想到了一些解决方案,但并不真正喜欢任何解决方案,因为它们看起来都不像我们以前见过的模式。
解决方案1:
function foo(data, deps = defaultDeps) {
return deps.process({
value: deps.extractBar(data.prop1),
otherValue: deps.extractBaz(data.prop2.someOtherProp)
});
}
解决方案2:
function foo(
data,
processImpl = process,
extractBarImpl = extractBar,
extractBazImpl = extractBaz
) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
foo
随着依赖函数调用数量的增加,解决方案 2 会很快污染方法签名。
解决方案3:
只需接受复杂的复合操作这一事实foo
并对其进行整体测试即可。所有的缺点都适用。
请提出其他可能性。我想这是函数式编程社区必须以某种方式解决的问题。