我正在使用Jest测试Redux动作函数fn1。 fn1是包装fn2的高阶函数。我的测试只是确保执行fn1时调用了fn2。似乎不起作用。我正在考虑使用jest.spyOn
,但似乎没有任何意义。
myActions.js:
export const fn1 = obj => {
return strInput => {
fn2(strInput, obj);
};
};
export const fn2 = (strInput, obj) => ({name:strInput, obj});
myAction.test.js:
import {fn1, fn2} from myAction.test.js
it("should call fn2", () => {
fn1({test:"test"})("David")
expect(fn2).toHaveBeenCalled();
});
从某种意义上说,我觉得您要尝试的是测试实现细节而不是功能的API,但是在单元测试中,您确实希望根据指定的条件测试或声明正确的输出。输入,即f(x) = y
,测试输入x
会产生输出y
。
[您的fn2
大概会有自己的单元测试,因此可以假定它已在其他功能(例如fn1
)中使用时进行了测试并正确。
这是我测试fn1
的方法:
it("should compute composed value", () => {
expect(fn1({ test: "test" })("David")).toEqual({
name: "David",
obj: { test: "test" }
});
});
我会说,监视或断言函数调用的典型用例是回调。回调不是函数实现的一部分,但通常是外部副作用。
const fn3 = (value, callback) => {
// bunch of code logic
callback(value);
// more code logic
return true;
};
it("should callback function", () => {
const cb = jest.fn();
fn3(3, cb);
expect(cb).toHaveBeenCalledWith(3);
});
信息不完全是答案的一部分
在这一点上,我想指出一个命名错误:高阶函数与Currying
A Higher Order Function是将一个功能作为输入并返回新功能的一个。示例包括.map
,.filter
,功能组成
const plus3 = x => x + 3; // a first order function
const double = (fn, v) => fn(v) * 2; // a higher order function
const plus3AndDouble = x => double(plus3, x); // a (decorated) first order function
console.log(plus3AndDouble(0)); // (0 + 3) * 2 = 6
console.log(plus3AndDouble(1)); // (1 + 3) * 2 = 8
您所完成的是实际上一个名为currying的概念,其中您采用了一个接受多个输入的函数,并将其转换为每个都接受一个输入的函数序列。
const foo = (a, b, c) => a + b * c;
const bar = a => b => c => foo(a, b, c);
console.log(foo(1, 2, 3) === bar(1)(2)(3)); // true