Jest 单元测试遇到 Error:Jest:jest.mock()
的模块工厂不允许引用任何超出作用域的变量
Jest 是一个流行的 JavaScript 测试框架,被广泛应用于前端开发。然而,在实际应用 Jest 进行单元测试时,很多开发者可能会遇到类似以下的错误提示信息:
Error: Jest: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
那么,这个 Error 是什么意思,为什么会出现这个错误,如何解决呢?请继续往下阅读。
错误解读
这个误报是由 Jest 版本升级导致的。在 Jest 25 中,引入了一个更加精准的 scope-hoisting 优化,从而导致了这个误报。
这个优化的目的是显而易见的:大大降低了模块加载的时间和内存开销并提升执行速度。事实上,这是一个非常有效的优化措施,但是,这个错误也是在优化的过程中被引入的。
问题分析
那么问题是出在哪里呢?
在使用 Jest 进行测试时,我们通常需要用 jest.mock()
函数来进行模块替代。通常情况下,我们需要从外部引用一些变量,然后将其传递给 jest.mock()
函数来进行替代。例如:
// app.js const db = require('./db'); // user.js jest.mock('./db')
然而,如果该变量不在 jest.mock()
函数的作用域范围内,就会遇到上述提到的 Error 信息。例如:
const db = require('./db'); const tableName = 'users'; jest.mock('./db', () => { return { query: jest.fn(), TABLE_NAME: tableName, // undefined } })
解决方案
那么,我们如何解决这个 Error 呢?
根据错误提示信息,很显然是把变量添加到 jest.mock()
函数内部的作用域中。改变量应该都是本地变量类型。我们可以使用闭包使得变量在内部被声明,例如:
-- -------------------- ---- ------- ----- -- - ---------------- ----- --------- - -------- ----------------- -- -- - ----- --------- - -------- ------ - ------ ---------- ----------- ---------- - --
此方法解决了由超出作用域变量引起的 Error 信息。还有一种方法是使用 moduleNameMapper
转换方法替代模块。例如:
moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1', '^~/(.*)$': '<rootDir>/test/$1' },
这种方法可以解决路径问题并可以更好地排除模块。
结论
Jest 单元测试是 Web 应用开发过程中不可或缺的工具,但是在实际应用中,我们需要遵循 Jest 约定,合理使用 jest.mock()
函数,遵循变量作用域规则等等。以上方法是解决 Error 信息的有效办法,希望对大家有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66c8ab367e58894c23c88925