监视在 Jest 中调用另一个函数的导入函数
Posted
技术标签:
【中文标题】监视在 Jest 中调用另一个函数的导入函数【英文标题】:Spying on an imported function that calls another function in Jest 【发布时间】:2018-11-24 01:14:12 【问题描述】:我试图监视一个由另一个函数调用的函数,这两个函数都驻留在外部文件中并导入。
Funcs.spec.js:
import * as Funcs from './Funcs'
describe('funcA', () =>
it('calls funcB', () =>
jest.spyOn(Funcs, 'funcB')
Funcs.funcA()
expect(Funcs.funcB).toHaveBeenCalled()
Funcs.js:
export const funcA = () =>
funcB()
export const funcB = () =>
由于某种原因,间谍在 Funcs.js 的范围内不受尊重。我能做些什么来监视 funcB 以便我知道 funcA 调用了它?
【问题讨论】:
【参考方案1】:只有方法可以被窥探。如果 funcB
在同一模块中像 funcB()
一样直接调用,则无法监视它。
为了监视或模拟导出的函数,funcA
和 funcB
应该位于不同的模块中。
这允许在 transpiled ES 模块中监视funcB
(模块对象在本机 ESM 中是只读的):
import funcB from './b';
export const funcA = () =>
funcB()
由于模块导入是模块的表示,因此被转译为:
var _b = require('./b');
var funcA = exports.funcA = function funcA()
(0, _b.funcB)();
;
funcB
方法与 _b
模块对象绑定在一起,因此可以监视它。
【讨论】:
这是正确的,但不完整。 OP 所要求的(测试在同一文件中导出的功能)可以在不拆分为不同文件/模块的情况下实现。如果您想知道如何查看我的answer。 @a--m 没有拆分成不同的文件/模块 - 这没有被列为要求。代码需要重构以提高可测试性,我只是建议了一种惯用的方法来提高可测试性。这是一个取舍,取决于监视 funcB 的重要性;可能是不必要的。是的,可以使用您建议的 CJS 模块,但 IMO 似乎有点太多了。由于此代码的上下文未知,因此无法保证 CJS 模块在应用程序中是合适的或受支持的(它们也不支持 tree-shaking)。 明白。我同意您关于拆分作为通用规则的测试改进的论点。但由于 OP 声明 它们都驻留在外部文件中并导入这一事实,我认为包括针对此特定要求的解决方案也很重要。事实上,我们在这里讨论的内容也是关于我提到的玩笑问题;)【参考方案2】:jest issue 引用了您描述的问题。
您的问题的一个可能解决方案(如果您想将函数保留在同一个文件中)是使用 CommonJS,请考虑以下示例:
fns.js
exports.funcA = () =>
exports.funcB();
;
exports.funcB = () => ;
fns.spec.js
const fns = require("./fns");
describe("funcA", () =>
it("calls funcB", () =>
fns.funcB = jest.fn();
fns.funcA();
expect(fns.funcB).toBeCalled();
);
);
【讨论】:
以上是关于监视在 Jest 中调用另一个函数的导入函数的主要内容,如果未能解决你的问题,请参考以下文章