Jest没有窥探对象

时间:2017-10-13 15:25:00

标签: javascript unit-testing ecmascript-6 jestjs

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

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

案例:有一个lol对象,其中包含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()
    });

});

1 个答案:

答案 0 :(得分:2)

Jest spyOn在内部替换具有间谍功能的对象方法 - 间谍功能是附加的'对象,它不会将原始函数包装到哪个对象属性指向。如果你在lol.b方法上设置间谍,Jest会做这样的事情(当然下面的代码是大量的简化,只是为了显示一般的想法):

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

let lol = {
    b: b
};

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

因此,如果你现在直接调用b(),那么间谍完全没有意识到这一点,因为在这种情况下不会调用jestSpyFunction - 只有在你使用lol.b()时才会调用它。登记/> 因此,在我看来,lol的第二个实现是正确的,应该这样做以使代码可测试。此外,您将ab功能定义为“私人”和“私人”功能。 (在匿名函数内)所以它是正确的和预期的行为,他们无法从外部范围访问(即使是间谍间谍)。