lub*_*bro 10 javascript testing typescript jestjs
我希望有人可以帮助我理解 js 原型和jest.spOn().
我有一个小示例:文件中的示例类TestObj.ts:
export default class TestObj {
foo() {
// Do Something e.g.
console.log("Hello World!");
}
}
Run Code Online (Sandbox Code Playgroud)
以下示例测试用例成功,但console.log从未执行。
import TestObj from './TestObj';
const spyObj = jest.spyOn(TestObj.prototype, 'foo');
test('debug test', () => {
const obj = new TestObj();
obj.foo();
expect(spyObj).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
如果我将示例测试用例更改为以下内容,则测试会成功并且该console.log语句将按预期调用。
import TestObj from './TestObj';
test('debug test', () => {
const spyObj = jest.spyOn(TestObj.prototype, 'foo');
const obj = new TestObj();
obj.foo();
expect(spyObj).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
知道为什么使用全局间谍变量的版本不能按预期工作吗?
它似乎与原型无关。对于没有任何类的函数也存在同样的问题,将第一个代码片段 ( TestObj.ts) 编辑为:
export foo() {
// Do Something e.g.
console.log("Hello World!");
};
Run Code Online (Sandbox Code Playgroud)
我们在更新的第二个片段中收到了同样的问题。(测试成功,但从未到达控制台日志。)
import * as testlib from './TestObj';
const spyObj = jest.spyOn(testlib, 'foo');
test('debug test', () => {
testlib.foo();
expect(spyObj).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
但是,如果我们将第二个代码片段更新为以下内容,则测试会成功并执行控制台日志:
import * as testlib from './TestObj';
const spyObj: jest.SpyInstance;
beforeEach(() => {
spyObj = jest.spyOn(testlib, 'foo');
});
test('debug test', () => {
testlib.foo();
expect(spyObj).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
但是我仍然不知道为什么会发现这个问题。
谁遇到过这篇文章,
我做了很多研究(try&error、mdn、jest manpage 和很多媒体文章),我想我找到了奇怪行为的原因。要理解这个问题,了解以下几点很重要:
jest.SpyOn(TestObj.prototype, 'foo');实际上实现为:TestObj.prototype.foo = new jest.fn().mockImplementation(()=>{original_TestObj.prototype.foo()});
这意味着监视类原型的函数实际上是在更改全局变量。spyOn似乎与它本身相同jest.fn(),是一个空实现,这意味着模型仍然可以调用,但没有代码,尤其是不执行原始实现。test('should foo', () => {
const testObj = new TestObj();
const spyOnFn = jest.spyOn(testObj, 'foo');
// Do anything
expect(spyOnFn).to//Have been anything
});
Run Code Online (Sandbox Code Playgroud)
spyOn在多个测试中实现相同的函数,请尝试为测试创建一个全局变量,但在 jest 的每个功能之前使用来设置 Spy。此功能在所有模拟重置后执行(如果启用)。例如:let spyOnFunction1: jest.SpyInstance;
beforeEach(()=> {
spyOnFunction1 = jest.spyOn(TestObj.prototype, 'foo');
});
Run Code Online (Sandbox Code Playgroud)