Jest. How to mock console when it is used by a third-party-library?

馋奶兔 提交于 2019-11-28 07:08:58

You have to use global to access objects in the global context

global.console = {warn: jest.fn()}
expect(console.warn).toBeCalled()

or use jest.spyOn added in 19.0.0

jest.spyOn(global.console, 'warn')

Use jest.spyOn() and spy.mockRestore().

const spy = jest.spyOn(console, 'warn').mockImplementation();
...
spy.mockRestore();

The accepted answer does not restore the original console.warn() and will "compromise" your other tests inside the same file (if they also use console.warn()).

FYI if you use console.warn = jest.fn() in a test file, it won't affect other test files (console.warn will be back to its original value).

Advice: it's best to call spy.mockRestore() inside afterEach()/afterAll() so you are sure that even if a test crashes, it won't compromise the others from the same file => ensures your tests inside the same file are fully isolated.

Full example:

const spy = jest.spyOn(console, 'warn').mockImplementation();
console.warn('message1'); // Won't be displayed (mocked)
console.warn('message2'); // Won't be displayed (mocked)
expect(console.warn).toHaveBeenCalledTimes(2);
expect(spy).toHaveBeenCalledTimes(2); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message2');
expect(spy).toHaveBeenLastCalledWith('message2'); // Another syntax
expect(spy.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);
spy.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax

console.warn('message3'); // Will be displayed (not mocked anymore)
expect(spy).toHaveBeenCalledTimes(0); // Not counting anymore
expect(spy.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash

You cannot write console.warn = jest.fn().mockImplementation() [...] console.warn.mockRestore() because it won't restore the original console.warn().

/!\ With mockImplementationOnce() you will still need to call spy.mockRestore():

// /!\
const spy = jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
console.warn('message1'); // Won't be displayed (mocked)
expect(console.warn).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledTimes(1); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message1');
expect(spy).toHaveBeenLastCalledWith('message1'); // Another syntax
expect(spy.mock.calls).toEqual([['message1']]);
expect(console.warn.mock.calls).toEqual([['message1']]);

console.warn('message2'); // Will be displayed (not mocked anymore)
// /!\
expect(console.warn).toHaveBeenCalledTimes(2); // BAD => still counting
expect(spy.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);

spy.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax
console.warn('message3'); // Will be displayed (not mocked anymore)
expect(spy).toHaveBeenCalledTimes(0); // Not counting anymore
expect(spy.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash

You can also write:

const assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!