Javascript 笑话:当第三方库使用控制台时,如何模拟控制台?

Javascript 笑话:当第三方库使用控制台时,如何模拟控制台?,javascript,unit-testing,tdd,jestjs,Javascript,Unit Testing,Tdd,Jestjs,我正在尝试模拟console.warn/error,但我无法。我使用第三方库,在其中调用console.warn。我需要测试一下它叫不叫。在我的测试用例中,我试图存根console.warn,但它没有帮助。之后,我试图手动模拟控制台,但也没有成功 console.warn = jest.fn(); testSchema('/app/components/Users/UserItem/UserItemContainer.js'); expect(console.warn).toBeCalled()

我正在尝试模拟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。有人能帮我吗?

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

global.console = {warn: jest.fn()}
expect(console.warn).toBeCalled()
或者使用
19.0.0

jest.spyOn(global.console, 'warn')
使用
jest.spyOn()
spy.mockRestore()

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

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

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

完整示例:

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 assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;

是的,伙计们,这很有效。但有一件事是,在声明global.console之后,必须需要lib。我做错了。我需要我的lib,然后声明为global。谢谢。有趣的是,Jest的网站上没有记录这一点。我正在搜索,找不到任何解释。对于typescript:error TS2322:Type“{warn:Mock;}”不能分配给Type“Console”。请大家注意
global.console={…}
将抑制错误,而
jest.spyOn(…)
将不抑制错误。您可以决定是否希望在测试中抑制错误。我更喜欢
jest.spyOn(…)
,因为它更容易清理,而且我使用的是TypeScript,但也希望像@a11smiles提到的那样抑制输出中的错误。因此,我使用了
jest.spyOn(global.console,“warn”).mockImplementation(()=>{})
来防止间谍通过底层
控制台调用。warn
这个解决方案对我不起作用;笑话25.5.4。它只是没有模仿控制台方法。调用次数为零,原始方法(
console.error
对我来说)仍然被调用。@cst1992嘿,你有没有找到其他方法来测试它,如果有,请告诉我们,那太好了,我也遇到了这个问题。@sakthisureshan还没有运气:(@cst1992哦,没有:(我也是,找不到雪人打算建议监视
globalThis.console
,而不仅仅是
console
,这对我很有效,但现在我发现普通的
console
也对我有效(笑话26.6),所以也许我只是幸运而已?:(祝你好运!
// /!\
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;