W naszym zespole programistów JavaScriptu zastosowaliśmy redux/reagujemy na styl pisania czystego kodu funkcjonalnego. Wydaje się jednak, że mamy problem z testowaniem naszego kodu przez jednostkę. Rozważmy następujący przykład:Jak przetestować drzewo czystych wywołań funkcji w izolacji?
function foo(data) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
Ta funkcja połączenia zależy od wezwań do process
, extractBar
i extractBaz
, z których każda może wywołać inne funkcje. Razem mogą wymagać nietrywialnej próby dla parametru data
do skonstruowania do testowania.
Jeśli zaakceptujemy konieczność stworzenia takiego symulowanego obiektu i faktycznie zrobimy to w testach, szybko stwierdzimy, że mamy przypadki testowe, które są trudne do odczytania i utrzymania. Co więcej, najprawdopodobniej prowadzi to do testowania tego samego w kółko, ponieważ prawdopodobnie należy również napisać testy jednostkowe dla process
, extractBar
i extractBaz
. Testowanie każdego możliwego przypadku krawędzi zaimplementowanego przez te funkcje za pomocą interfejsu foo
jest niewygodne.
Mamy kilka rozwiązań na uwadze, ale tak naprawdę nie lubimy, ponieważ żaden z nich nie wydaje się być wzorem, który wcześniej widzieliśmy.
Rozwiązanie 1:
function foo(data, deps = defaultDeps) {
return deps.process({
value: deps.extractBar(data.prop1),
otherValue: deps.extractBaz(data.prop2.someOtherProp)
});
}
Rozwiązanie 2:
function foo(
data,
processImpl = process,
extractBarImpl = extractBar,
extractBazImpl = extractBaz
) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
Rozwiązanie 2 zanieczyszcza foo
metoda podpis bardzo szybko, jak liczba połączeń wzrasta funkcją zależną.
Rozwiązanie 3:
Wystarczy zaakceptować fakt, że foo
jest skomplikowana operacja związek i przetestować go jako całość. Obowiązują wszystkie wady.
Proszę sugerować inne możliwości. Wyobrażam sobie, że jest to problem, który społeczność programowania funkcjonalnego musiała rozwiązać w taki czy inny sposób.