web-dev-qa-db-fra.com

Plaisanter. Comment se moquer de la console quand il est utilisé par une bibliothèque tierce?

J'essaie de me moquer de console.warn/error mais je ne peux pas. J'utilise une bibliothèque tierce qui appelle console.warn à l'intérieur. J'ai besoin de tester était-il appelé ou n'était pas. Dans mon cas de test, j'essayais de stub console.warn mais cela n'a pas aidé. Après cela, j'ai essayé de me moquer de la console manuellement, ça n'a pas marché non plus.

console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
expect(console.warn).toBeCalled();

n'a pas fonctionné

console.warn = jest.fn();
testSchema('/app/components/Users/UserItem/UserItemContainer.js');
console.warn('error');
expect(console.warn).toBeCalled();

a fonctionné. Mais je vois toujours console.warn node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:138 dans le terminal. Quelqu'un peut-il m'aider?

44
Errorpro

Vous devez utiliser global pour accéder aux objets dans le contexte global

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

ou utiliser jest.spyOn ajouté dans 19.0.0

jest.spyOn(global.console, 'warn')
89
Andreas Köberle

Utilisez jest.spyOn() et spy.mockRestore().

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

La réponse acceptée ne restaure pas l'original console.warn() et "compromettra" vos autres tests dans le même fichier (s'ils utilisent également console.warn()).

Pour votre information, si vous utilisez console.warn = jest.fn() dans un fichier test, cela n’affectera pas les autres fichiers test (console.warn reviendra à sa valeur initiale).

Conseil: Mieux vaut appeler spy.mockRestore() à l'intérieur de afterEach()/afterAll() pour être sûr que même si un test se bloque, il ne compromettra pas les autres. file => assure que vos tests dans le même fichier sont complètement isolés.

Exemple complet:

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

Vous ne pouvez pas écrire console.warn = jest.fn().mockImplementation() [...] console.warn.mockRestore() car il ne restaure pas l'original console.warn().

/!\Avec mockImplementationOnce(), vous devrez toujours appeler 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

Vous pouvez aussi écrire:

const assert = console.assert;
console.assert = jest.fn();
...
console.assert = assert;
9
tanguy_k