javascript - Jest 未能监视对象

标签 javascript unit-testing ecmascript-6 jestjs

我们在使用 Jest 进行单元测试时遇到了一个令人不安的错误。

问题:Jest无法访问内部对象方法

案例:有一个lol对象,有a和b()方法,如果我们直接调用b方法, Jest 失败了,如果我们用 lol.b() 调用它,它就可以工作

有人遇到过这个问题吗?有更好的解决方法吗?

代码:

describe('Jest bug', () => {    
    it('Jest fail', () => {
        const lol = (() => {
            const a = () => {
                console.log("console a");
                b();
            };
            const b = () => {
                console.log("console b");
            };
            return {
                a,
                b
            };
        })();

        const spy = jest.spyOn(lol, 'b');

        lol.a();

        expect(spy).toHaveBeenCalled()
    });

    it('Jest success', () => {
        const lol = (() => {
            const a = () => {
                console.log("console OK a");
                lol.b();
            };
            const b = () => {
                console.log("console OK b");
            };
            return {
                a,
                b
            };
        })();

        const spy = jest.spyOn(lol, 'b');

        lol.a();

        expect(spy).toHaveBeenCalled()
    });

});

最佳答案

Jest spyOn 在内部用 spy 函数替换对象方法 - spy 函数“附加”到对象,它不会包装对象属性指向的原始函数。如果你在 lol.b 方法上设置 spy ,Jest 会执行类似的操作(当然下面的代码是巨大的简化,只是为了展示总体思路):

let b = function() {
  ...
}; 

let lol = {
    b: b
};

spyOn(lol, 'b');
//Jest internally does something like this
lol.b = function jestSpyFunction() {
   ...
};

因此,如果您现在直接调用 b(),Jest spy 完全不知道这一点,因为在这种情况下不会调用 jestSpyFunction - 只有当您使用lol.b()
因此,在我看来,您的 lol 的第二个实现是正确的,应该以这种方式完成以使代码可测试。此外,您将 ab 函数定义为“私有(private)”(在匿名函数内部),因此它们无法从外部作用域访问(即使通过 Jest spy )。

关于javascript - Jest 未能监视对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733217/

相关文章:

javascript - 使用 Fetch 和 FormData API 上传多个文件

javascript - 解构函数参数子属性

javascript - Google 脚本将一个单元格写入另一个电子表格中的范围

javascript - sinon.stub() vs sinon.sandbox.stub()?

javascript - 拖放多个图像,在客户端调整它们的大小并获取调整大小的图像

c# - 在构建服务器 : Release or Debug code? 上进行单元测试

Python 单元测试/测试夹具测试模块是否已加载

elasticsearch - 如何在 redux saga 中使用 async await?

javascript - 我无法在其他 Node 模块工作时导入其中一个 Node 模块

javascript - JavaScript 是如何在 Google V8 中执行的,特别是 Canvas 相关代码