В некотором смысле, я чувствую, что вы пытаетесь протестировать детали реализации, а не 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);
});
Не совсем часть ответа, но информативная
At В этой точке я хочу указать на ошибку в номенклатуре: Функция высшего порядка по сравнению с карри
A Функция высшего порядка - это функция, которая принимает в качестве входных данных функцию и возвращает новую функцию. Примеры включают .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
Вы достигли на самом деле концепции под названием curry , в которой вы берете функцию, которая принимает несколько входов, и конвертируете ее к последовательности функций, каждая из которых принимает один вход.
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