#javascript #testing #functional-programming
Вопрос:
У меня есть функция MyComposedFunction
, которая представляет собой функциональную композицию из 3 функций , вторая функция fn2
, выполняет запрос POST (побочный эффект), используя результат fn1
и передает это значение fn3
.
const fn2 = async (fn1Result) => {
const result = await fetch(fn1Result.url, fn1Result.payload);
// some business logic
return fn2Results;
};
const MyComposedFunction = compose(fn3, fn2, fn1);
// My Test
expect(MyComposedFunction('hello world')).toBe('expected result');
Я бы хотел избежать написания модульных тестов для fn3
, fn2
, и fn1
и вместо этого только для тестирования MyComposedFunction
. Мое обоснование состоит в том, что не должно иметь значения, MyComposedFunction
используется compose(...)
или является одной длинной гигантской функцией, пока MyComposedFunction
она работает.
Можно ли написать тест MyComposedFunction
без необходимости издеваться fn2
?
Я бы подумал, что это, должно быть, относительно распространенная ситуация, когда вы пытаетесь выполнять функциональное программирование на JavaScript, но до сих пор не смогли найти полезный ресурс.
Комментарии:
1. Важным аспектом FP является отделение чистого кода от нечистого и попытка оставить как можно больше кода чистым. Обычно вы достигаете этой цели, откладывая оценку эффектов как можно дольше (например, с приложениями/монадами). Теперь вы можете протестировать обе части по отдельности, но вам все равно нужны насмешки над нечистой.
Ответ №1:
Вы можете ввести fetch в свою функцию, например, так
const fn2Thunk = (fetcher = fetch) => async (fn1Result) => {
const result = await fetcher(fn1Result.url, fn1Result.payload);
// some business logic
return fn2Results;
};
const fetchMock = async () => ({ result: "blah" })
const MyComposedFunctionTest = compose(fn3, fn2Thunk(fetchMock), fn1);
// My Test
const result = await MyComposedFunctionTest('hello world')
expect(result).toBe('expected result');