[英]How to know if a function definition has been changed in NodeJS?
我正在嘗試為一些時間密集型功能(網絡請求/計算繁重)編寫緩存系統,並且我需要從功能中生成指紋,以便在開發人員更改功能后使緩存結果無效。
我嘗試了以下方法來生成指紋:
const crypto = require('crypto')
const generateFingerprintOfFunc = (inputFunc) => {
const cypher = crypto.createHash('sha256');
cypher.update(inputFunc.toString());
return cypher.digest('hex');
}
但是,這種方法的問題在於,一旦開發人員更改了正在被指紋識別的 function 中調用的任何函數,指紋就不會被更改,因為該函數的定義並沒有真正改變。
const foo = () => {
return bar() + 1;
}
const bar = () => {
return 1;
}
const fingerprintOfFoo = generateFingerprintOfFunc(foo); // 489290d22f653965a59e2e5fbb7b626535babd660f7f49501fc88c3e7fbc0176
現在我將更改bar
function:
const foo = () => {
return bar() + 1;
}
const bar = () => {
return 10;
}
const fingerprintOfFoo = generateFingerprintOfFunc(foo); // 489290d22f653965a59e2e5fbb7b626535babd660f7f49501fc88c3e7fbc0176
如您所見,指紋沒有改變,而 function 的返回值有。
為什么我需要這樣做?
我正在嘗試在開發和測試期間為我昂貴的功能生成動態和自動模擬。 看到這個問題
我想知道 v8 是否有辦法為我提供構成某個 function 及其所有內部結構的文件的路徑。
不。
它不能。 JavaScript 太動態了。
考慮這個例子:
let helper;
const foo = () => helper() + 1;
const bar = () => 1;
const baz = () => 2;
helper = bar;
到目前為止,這與您的示例相同。 現在假設有人將最后一行更改為 read,或者添加了一個新行,內容為helper = baz
。 在這種情況下,沒有函數的定義發生變化,但foo
的行為發生了變化,事實上:人們可以采用相同的想法來構造一個更簡單的情況:
let global = 42;
const foo = () => global;
如果有人更改global
(無論是在源中靜態還是動態), foo
的返回值將會改變,但沒有 function 定義會改變。 在動態分配的情況下,甚至源中的任何內容都不會改變。 當然,這樣的分配可能取決於任意條件/情況,例如用戶交互、一天中的時間、 Math.random()
等等。
一般來說,唯一的方法(對於任何人,包括引擎)來說,弄清楚 function 將返回什么是執行它。
如果開發人員仔細選擇適合記憶化的功能,記憶化就會起作用。
采用任意 function(不對 function 的功能施加任何限制)並記住它,或者確定它是否與上次相同的值而不實際執行它的自動化系統,是不可能在 Z6836155AF75A7F14D 中創建的。
當您說“更改功能”時,您是什么意思? 例如,您在觀看模式下開玩笑,並且只想在發生根本變化時才接受更改? 我認為真正的問題是為什么這是必要的,首先。
你是如何生成動態模擬的? 這是否意味着您重復使用網絡請求實時創建這些模擬? 然后他們不是真正的嘲笑。 您只是提出真正的請求,然后決定將其臨時存儲在某個地方。 您可以跳過該數據保存步驟,您的測試過程將是相同的。 這是一個美化的集成測試
我想其他人可能不同意,但你的單元測試理念似乎有點缺陷。 動態模擬意味着您無法控制最終要測試的情況。 如果你不能完全控制你的模擬,你不能最終重復測試完全相同的情況(或邊緣情況)嗎? 這是對資源的浪費,並且可能導致有缺陷的測試。 涵蓋您所有預期的情況將是巧合,而不是明確的意圖。 您的單元測試應該是確定性的。 不是隨機的。
看起來你需要解決你的測試方法,而不是接受你的測試很慢並制定如何解決它的策略。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.