Jest:第三方库使用时如何模拟控制台?
Jest: how to mock console when it is used by a third-party-library?
我正在尝试模拟控制台。warn/error 但我不能。我使用了一个在其中调用 console.warn 的第三方库。我需要测试它是否被调用。在我的测试用例中,我试图存根 console.warn 但它没有帮助。之后我尝试手动模拟控制台,但也没有成功。
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
expect(console.warn).toBeCalled();
没用
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
console.warn('error');
expect(console.warn).toBeCalled();
成功了。
但我仍然在终端中看到 console.warn node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:138
。
您必须使用 global
来访问全局上下文中的对象
global.console = {warn: jest.fn()}
expect(console.warn).toBeCalled()
或使用 jest.spyOn
添加到 19.0.0
jest.spyOn(global.console, 'warn')
使用jest.spyOn()
和mockRestore()
。
const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();
...
consoleWarnMock.mockRestore();
接受的答案不会恢复原来的 console.warn()
,并且会“损害”同一文件中的其他测试(如果 console.warn()
用于其他测试或正在测试的代码中)。
仅供参考,如果您在测试文件中使用 console.warn = jest.fn()
,它不会影响其他测试文件(例如 console.warn 将在其他测试文件中恢复为原始值)。
建议:您可以在 afterEach()
/afterAll()
中调用 consoleWarnMock.mockRestore()
以确保即使测试崩溃,它也不会危及同一文件中的其他测试(例如,确保同一文件中的测试完全隔离)。
完整示例:
const consoleWarnMock = 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(consoleWarnMock).toHaveBeenCalledTimes(2); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message2');
expect(consoleWarnMock).toHaveBeenLastCalledWith('message2'); // Another syntax
expect(consoleWarnMock.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);
consoleWarnMock.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax
console.warn('message3'); // Will be displayed (not mocked anymore)
expect(consoleWarnMock).toHaveBeenCalledTimes(0); // Not counting anymore
expect(consoleWarnMock.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash
你不能写
console.warn = jest.fn().mockImplementation();
...
console.warn.mockRestore();
因为它不会恢复原来的console.warn()
。
/!\ 使用 mockImplementationOnce()
你仍然需要调用 consoleWarnMock.mockRestore()
:
// /!\
const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
console.warn('message1'); // Won't be displayed (mocked)
expect(console.warn).toHaveBeenCalledTimes(1);
expect(consoleWarnMock).toHaveBeenCalledTimes(1); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message1');
expect(consoleWarnMock).toHaveBeenLastCalledWith('message1'); // Another syntax
expect(consoleWarnMock.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(consoleWarnMock.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);
consoleWarnMock.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax
console.warn('message3'); // Will be displayed (not mocked anymore)
expect(consoleWarnMock).toHaveBeenCalledTimes(0); // Not counting anymore
expect(consoleWarnMock.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash
你也可以这样写:
const assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;
您可以尝试以下操作,测试并确保在您的 jest 配置文件中包含 clearMocks
到 true
。
test('it should console warn a message', ()=>{
jest.spyOn(global.console, 'warn').mockImplementation();
console.warn('my error');
expect(console.warn).toBeCalledTimes(1)
expect(console.warn).toBeCalledWith('my error');
})
module.exports = {
...
clearMocks: true,
...
}
我正在尝试模拟控制台。warn/error 但我不能。我使用了一个在其中调用 console.warn 的第三方库。我需要测试它是否被调用。在我的测试用例中,我试图存根 console.warn 但它没有帮助。之后我尝试手动模拟控制台,但也没有成功。
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
expect(console.warn).toBeCalled();
没用
console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
console.warn('error');
expect(console.warn).toBeCalled();
成功了。
但我仍然在终端中看到 console.warn node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:138
。
您必须使用 global
来访问全局上下文中的对象
global.console = {warn: jest.fn()}
expect(console.warn).toBeCalled()
或使用 jest.spyOn
添加到 19.0.0
jest.spyOn(global.console, 'warn')
使用jest.spyOn()
和mockRestore()
。
const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();
...
consoleWarnMock.mockRestore();
接受的答案不会恢复原来的 console.warn()
,并且会“损害”同一文件中的其他测试(如果 console.warn()
用于其他测试或正在测试的代码中)。
仅供参考,如果您在测试文件中使用 console.warn = jest.fn()
,它不会影响其他测试文件(例如 console.warn 将在其他测试文件中恢复为原始值)。
建议:您可以在 afterEach()
/afterAll()
中调用 consoleWarnMock.mockRestore()
以确保即使测试崩溃,它也不会危及同一文件中的其他测试(例如,确保同一文件中的测试完全隔离)。
完整示例:
const consoleWarnMock = 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(consoleWarnMock).toHaveBeenCalledTimes(2); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message2');
expect(consoleWarnMock).toHaveBeenLastCalledWith('message2'); // Another syntax
expect(consoleWarnMock.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);
consoleWarnMock.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax
console.warn('message3'); // Will be displayed (not mocked anymore)
expect(consoleWarnMock).toHaveBeenCalledTimes(0); // Not counting anymore
expect(consoleWarnMock.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash
你不能写
console.warn = jest.fn().mockImplementation();
...
console.warn.mockRestore();
因为它不会恢复原来的console.warn()
。
/!\ 使用 mockImplementationOnce()
你仍然需要调用 consoleWarnMock.mockRestore()
:
// /!\
const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
console.warn('message1'); // Won't be displayed (mocked)
expect(console.warn).toHaveBeenCalledTimes(1);
expect(consoleWarnMock).toHaveBeenCalledTimes(1); // Another syntax
expect(console.warn).toHaveBeenLastCalledWith('message1');
expect(consoleWarnMock).toHaveBeenLastCalledWith('message1'); // Another syntax
expect(consoleWarnMock.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(consoleWarnMock.mock.calls).toEqual([['message1'], ['message2']]);
expect(console.warn.mock.calls).toEqual([['message1'], ['message2']]);
consoleWarnMock.mockRestore(); // IMPORTANT
//console.warn.mockRestore(); // Another syntax
console.warn('message3'); // Will be displayed (not mocked anymore)
expect(consoleWarnMock).toHaveBeenCalledTimes(0); // Not counting anymore
expect(consoleWarnMock.mock.calls).toEqual([]);
//expect(console.warn.mock.calls).toEqual([]); // Crash
你也可以这样写:
const assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;
您可以尝试以下操作,测试并确保在您的 jest 配置文件中包含 clearMocks
到 true
。
test('it should console warn a message', ()=>{
jest.spyOn(global.console, 'warn').mockImplementation();
console.warn('my error');
expect(console.warn).toBeCalledTimes(1)
expect(console.warn).toBeCalledWith('my error');
})
module.exports = {
...
clearMocks: true,
...
}