开玩笑:第三方库使用控制台时如何模拟控制台?


79

我正在尝试模拟console.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在终端中看到。谁能帮我?

Answers:


140

您必须使用global来访问全局上下文中的对象

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

或使用jest.spyOn添加19.0.0

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

2
是的,它有效。但是有一件事是,在声明global.console之后,您必须要求lib。我做错了。我需要我的lib,然后将其声明为global。谢谢。
Errorpro

1
有趣的是,Jest网站上的任何地方都没有对此进行记录。我正在搜索,找不到任何可以解释的内容。
莱昂纳多

1
带有打字稿:错误TS2322:键入'{警告:Mock <{}>;}”不可分配给“控制台”类型。
Gerard Brull

8
只是让每个人都知道。global.console = {...}抑制错误,而jest.spyOn(...)不会。您可以决定是否要在测试中消除错误。
a11smiles

37
我更喜欢,jest.spyOn(...)因为它更容易清理,而且我正在使用TypeScript,但也想抑制输出中的错误,如@ a11smiles所述。因此,我使用jest.spyOn(global.console, "warn").mockImplementation(() => {})了防止间谍调用的方法console.warn
djskinner

68

使用jest.spyOn()spy.mockRestore()

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

接受的答案不会还原原始答案,console.warn()并且会“破坏”同一文件中的其他测试(如果console.warn()在其他测试或正在测试的代码中使用)。

仅供参考,如果您console.warn = jest.fn()在测试文件中使用它,则不会影响其他测试文件(例如console.warn将恢复为其他测试文件中的原始值)。

建议:您可以spy.mockRestore()afterEach()/内部调用afterAll(),以确保即使测试崩溃,也不会破坏同一文件中的其他测试(例如,确保完全隔离同一文件中的测试)。

完整示例:

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

您无法编写文字,console.warn = jest.fn().mockImplementation() [...] console.warn.mockRestore()因为它无法还原原始文字console.warn()

/!\mockImplementationOnce()您仍然需要致电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

您还可以编写:

const assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.