web-dev-qa-db-ja.com

冗談。サードパーティのライブラリで使用されているコンソールをモックする方法は?

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が表示されます。誰も私を助けることができますか?

44
Errorpro

グローバルコンテキストのオブジェクトにアクセスするには、globalを使用する必要があります

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

またはjest.spyOnに追加された19.0.0を使用します

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

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;
9
tanguy_k