如何测试私有范围或匿名函数?

时间:2021-01-08 22:50:57

标签: javascript unit-testing testdoublejs

假设我有以下模块:

foo.js

module.exports = function (x, f) {
  f(x);
};

bar.js

const foo = require('./foo');

module.exports = function () {
  foo(40, n => n + 2);
  //      ^
  //      f — How can I test this lambda?
};

我只需要断言,当调用 bar 时,foo 的调用完全如上所示 ^

我可以测试 foo 是否已使用 40 调用,如下所示:

const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');

bar();

td.verify(foo(40, td.matchers.anything())); // Pass

但是我如何验证函数 f 是一个函数,它接受一个数字,将其加 2 并返回结果?

PS:我清楚地意识到这并不能完全测试最佳实践 101。如果我有机会以不同的方式做事,我宁愿不以这种方式进行测试。所以请幽默我。

1 个答案:

答案 0 :(得分:0)

我找到了两种方法:

td.matchers.argThat

这个匹配器采用一个取其位置参数值的谓词:

const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');

bar();

td.verify(foo(40, td.matchers.argThat(f => f(40) === 42))); // Pass

td.matchers.captor

有一个称为 captor 的特殊匹配器,它捕获其位置参数并在稍后通过匹配器的 .value 属性使其可用:

const tap = require('tap');
const td = require('testdouble');
const foo = td.replace('./foo');
const bar = require('./bar');
const f = td.matchers.captor();

bar();

td.verify(foo(40, f.capture()));

tap.equal(f.value(40), 42); // Pass
tap.equal(f.value(50), 52); // Pass
tap.equal(f.value(60), 62); // Pass