我正在尝试测试应用,但jest.spyOn让我发疯。
我正在研究节点v8.9.4和jest v22.2.2
我已经提取了这段代码:
// my-module.js
class MySingletonModule {
constructor() {
this.foo = 'bar';
}
myPromise() {
return new Promise((resolve, reject) => resolve(this.foo));
}
}
module.exports = new MySingletonModule();
// promise.test.js
const singleton = require('./my-module');
describe('Module test-suite', () => {
let spy;
beforeAll(async () => {
spy = jest.fn();
spy = jest.spyOn(singleton, 'myPromise');
});
beforeEach(() => spy.mockReset());
test('Check bar', () => {
return singleton.myPromise().then((bar) => {
expect(bar).toEqual('bar');
});
});
test('Check called times', () => {
singleton.myPromise();
expect(spy).toHaveBeenCalledTimes(1);
});
afterAll(() => {
jest.restoreAllMocks();
});
});
Check bar
测试失败,因为myPromise
方法未返回承诺:
如果我评论spy = jest.spyOn(singleton, 'myPromise');
测试工作..但显然其他测试不起作用..
我希望所有测试都适用于spyOn
,因为阅读文档时写道:
注意:默认情况下,jest.spyOn也会调用spied方法。
我错过了什么?
感谢您的帮助
答案 0 :(得分:1)
我在文档中看不到这一点,但似乎jest允许你使用很多Jasmine的功能/语法,包括.and.callThrough
:
beforeEach(() => {
spyOn(singleton, 'myPromise').and.callThrough();
};
test('Check bar', async () => {
const bar = await singleton.myPromise();
expect(bar).toEqual('bar');
});
test('Check called times', () => {
singleton.myPromise();
expect(singleton.myPromise.calls.count()).toBe(1);
});
以下是茉莉花间谍文档:https://jasmine.github.io/2.0/introduction.html#section-Spies
如果您想坚持使用已记录的jest.spyOn
API,那么您可以在使用它的测试中设置间谍,这样它就不会影响另一个:
test('Check bar', async () => {
const bar = await singleton.myPromise();
expect(bar).toEqual('bar');
});
test('Check called times', () => {
const spy = jest.spyOn(singleton, 'myPromise');
singleton.myPromise();
expect(spy).toHaveBeenCalledTimes(1);
});
答案 1 :(得分:0)
这是没有Jasmine的工作片段:
describe('Module test-suite', () => {
let spy;
beforeAll(() => { // get rid of async
spy = jest.fn();
spy = jest.spyOn(singleton, 'myPromise');
});
afterEach(() => spy.mockRestore()); // main difference is here
test('Check bar', () => {
return singleton.myPromise().then((bar) => {
expect(bar).toEqual('bar');
});
});
test('Check called times', () => {
singleton.myPromise();
expect(spy).toHaveBeenCalledTimes(1);
});
afterAll(() => {
jest.restoreAllMocks();
});
});
我认为最好使用mockRestore
代替mockReset
,因为据我所知jest docs mockReset
几乎无法清除有关间谍和间谍对象的所有信息。并且mockRestore
只清除一些临时数据,例如被叫次数。
为什么使用afterEach
代替beforeEach
很重要 - 我不知道:(
我也删除了async
,因为测试失败了。