【发布时间】:2017-01-15 01:27:15
【问题描述】:
我一直在考虑如何测试同一文件中其他函数使用的特定函数。
例如,假设我在一个文件中有两个函数:
// validators.js
export const required = ...;
export const containsUppercase = ...;
export const containsNumber = ...;
export const password = (val) => [required, containsUppercase, containsNumber].every(f => f(val));
很明显,密码验证器取决于required、containsUppercase 和containsNumber 函数。但是,如果我想将它们存根怎么办,所以我的测试实际上不必关心这些函数或它们如何验证。
这是一个简单而愚蠢的例子,但我在更复杂的场景中遇到了同样的问题。
例如,如果我尝试使用 sinon 执行此操作,我可能会尝试执行此操作:
import * as validators from './validators';
sinon.stub(validators, 'required').returns(false);
sinon.stub(validators, 'containsUppercase').returns(true);
sinon.stub(validators, 'containsNumber').returns(true);
// test
expect(validators.password('notImportant')).toBe(false);
我试过这样做,但我无法让它工作。我发现我可以让它工作,如果我做这样的事情,虽然我还没有测试过。
const required = ...;
const containsUppercase = ...;
const containsNumber = ...;
const password = (val) => [ex.required, ex.containsUppercase, ex.containsNumber].every(f => f(val));
export default ex = {
required,
containsUppercase,
containsNumber,
password,
}
这个解决方案也很丑,因为我现在不得不担心将函数导出到正确的位置,并且还要通过导出对象引用它。
有没有更清洁的方法来做到这一点?或者更确切地说,测试这些功能的最佳方法是什么?
【问题讨论】:
-
查看
rewire。 编辑:没关系,rewire与const有问题。 -
哦,真令人失望。我一直在看 babel-plugin-rewire,因为从文档来看,rewire 本身似乎不适用于 es6。但是如果它不支持
const,那就不行了。 -
不过,你可以试试看
babel-plugin-rewire是否有效。 -
可测试性是使用 IoC/DI 的一个很好的理由,例如 this library(深受 Angular 2 DI 的启发)。
-
这真的很酷,但不幸的是,我不使用打字稿。另外,我对依赖注入非常熟悉,但每次都必须调用
password(requiredFn, uppercaseFn, numberFn, val)对我来说似乎不是很吸引人。我也考虑过更改函数以允许部分应用:const password = (required, uppercase, number) => val => ...,但是对于这样一个简单的示例来说,这会增加很多复杂性,所以它似乎不可行。
标签: javascript testing ecmascript-6 sinon