[英]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.