私たちの JavaScript 開発者チームでは、純粋な機能コードを書くための redux/react スタイルを採用しています。ただし、コードの単体テストに問題があるようです。次の例を検討してください。
function foo(data) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
process
この関数呼び出しは、 、 、および の呼び出しに依存してextractBar
おりextractBaz
、それぞれが他の関数を呼び出すことができます。data
一緒に、それらは、テスト用に構築されるパラメーターの重要なモックを必要とする場合があり ます。
そのようなモック オブジェクトを作成する必要性を受け入れて、実際にテストで作成すると、読み取りや保守が困難なテスト ケースがあることがすぐにわかります。さらに、 の単体テストのように、同じことを何度もテストすることにつながる可能性が非常に高く、おそらくそれprocess
も書かれるべきです。インターフェイスを介してこれらの関数によって実装される可能性のある各エッジ ケースのテストは扱いにくいです。extractBar
extractBaz
foo
いくつかの解決策を念頭に置いていますが、どちらも以前に見たパターンのようには見えないため、どれも気に入りません。
解決策 1:
function foo(data, deps = defaultDeps) {
return deps.process({
value: deps.extractBar(data.prop1),
otherValue: deps.extractBaz(data.prop2.someOtherProp)
});
}
解決策 2:
function foo(
data,
processImpl = process,
extractBarImpl = extractBar,
extractBazImpl = extractBaz
) {
return process({
value: extractBar(data.prop1),
otherValue: extractBaz(data.prop2.someOtherProp)
});
}
foo
解決策 2では、依存する関数呼び出しの数が増えると、メソッド シグネチャが急速に汚染されます。
解決策 3:
複雑な複合操作であるという事実を受け入れてfoo
、全体としてテストしてください。すべての欠点が当てはまります。
他の可能性を提案してください。これは、関数型プログラミング コミュニティが何らかの方法で解決したに違いない問題だと思います。