在我們的JavaScript開發團隊中,我們已經接受了編寫純功能代碼的減少/反應風格。但是,我們似乎無法單元測試我們的代碼。請看下面的例子:如何單獨測試一個純函數調用樹?
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)
});
}
溶液2非常迅速地調用相關函數的數量的增加污染foo
方法簽名。
解決方案3:
只要接受一個事實,即foo
是一個複雜的複合操作,並測試它作爲一個整體。所有缺點都適用。
請提出其他可能性。我想這是功能編程社區必須以某種方式解決的問題。