我们在使用 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
的第二个实现是正确的,应该以这种方式完成以使代码可测试。此外,您将 a
和 b
函数定义为“私有(private)”(在匿名函数内部),因此它们无法从外部作用域访问(即使通过 Jest spy )。
关于javascript - Jest 未能监视对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733217/