如何知道NodeJS中的函数定义是否发生了更改



我正试图为一些时间密集型函数(网络请求/计算量大(编写一个缓存系统,我需要从这些函数中生成指纹,以便在开发人员更改函数后使缓存的结果无效。

我尝试了以下方法来生成指纹:

const crypto = require('crypto')
const generateFingerprintOfFunc = (inputFunc) => {
const cypher = crypto.createHash('sha256');
cypher.update(inputFunc.toString());
return cypher.digest('hex');
}

然而,这种方法的问题是,一旦开发人员更改了被指纹识别的函数内部调用的任何函数,指纹就不会改变,因为该函数的定义并没有真正改变。

const foo = () => {
return bar() + 1;
}
const bar = () => {
return 1;
}

const fingerprintOfFoo = generateFingerprintOfFunc(foo); // 489290d22f653965a59e2e5fbb7b626535babd660f7f49501fc88c3e7fbc0176

现在我将更改bar功能:

const foo = () => {
return bar() + 1;
}
const bar = () => {
return 10;
}
const fingerprintOfFoo = generateFingerprintOfFunc(foo); // 489290d22f653965a59e2e5fbb7b626535babd660f7f49501fc88c3e7fbc0176

正如你所看到的,指纹没有改变,而函数的返回值已经改变。

为什么我需要这样做?

在开发和测试过程中,我试图为我昂贵的函数生成动态和自动的mock。请参阅此SO问题

我想知道v8是否有办法为我提供组成某个函数的文件的路径及其所有内部内容。

否。

它不能。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的返回值都会更改,但函数定义不会更改。在动态分配的情况下,甚至源中的任何内容都不会更改。当然,这样的分配可能取决于任意的条件/环境,例如用户交互、一天中的时间、Math.random()等等。

一般来说,(包括引擎在内的任何人(要想知道函数会返回什么,唯一的方法就是执行它。
如果开发人员仔细选择适合记忆的函数,记忆化就会起作用
一个自动化系统,如果接受任何任意函数(不对函数的作用施加任何限制(并对其进行记忆,或者在没有实际执行的情况下确定其值是否与上次相同,则不可能在JavaScript中创建。

当你说"改变函数";?就像在中一样,你在观察模式中开玩笑,只想在做出基本更改时才进行更改?我认为真正的问题是,为什么这是必要的,首先。

  1. 如何生成动态模拟?这是否意味着您通过网络请求重复创建这些实时模拟?那么它们就不是真正的嘲弄。你只是提出了真正的请求,然后决定将其临时存储在某个地方。您可以跳过数据保存步骤,结果测试过程将完全相同。这是一个荣耀的集成测试

  2. 我想其他人可能不同意,但你的单元测试哲学似乎有点缺陷。动态模拟意味着您无法控制最终要测试的情况。如果你不能完全控制你的模拟,你就不能重复测试完全相同的情况(或边缘情况(吗?这是对资源的浪费,并可能导致有缺陷的测试。涵盖你所有的预期案例都是巧合,而不是明确的意图。您的单元测试应该是确定性的。不是随机的。

你似乎需要解决你的测试方法,而不是接受你的测试很慢,并制定如何解决它的策略。

相关内容

最新更新