I am trying to mock console.warn/error but i can't. I use a third-party-library which calls console.warn inside it. I need to test was it called or wasn't. In my test case i was trying to stub console.warn but it didn't help. After that i was trying to mock console manually it didn't work out either.
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
expect(console.warn).toBeCalled();
didn't work
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
console.warn('error');
expect(console.warn).toBeCalled();
did work. But i still see console.warn node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:138
in the terminal. Can anyone help me?
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;
来源:https://stackoverflow.com/questions/41223963/jest-how-to-mock-console-when-it-is-used-by-a-third-party-library