Jest: Wie verspottet man eine Konsole, wenn sie von einer Drittanbieter-Bibliothek verwendet wird?

79

Ich versuche, console.warn / error zu verspotten, aber ich kann nicht. Ich benutze eine Drittanbieter-Bibliothek, die console.warn darin aufruft. Ich muss testen, ob es heißt oder nicht. In meinem Testfall habe ich versucht, console.warn zu stubben, aber es hat nicht geholfen. Danach habe ich versucht, die Konsole manuell zu verspotten, es hat auch nicht geklappt.

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

hat nicht funktioniert

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

funktionierte. Aber ich sehe immer noch console.warn node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:138im Terminal. Kann mir jemand helfen?

Errorpro
quelle

Antworten:

140

Sie müssen verwenden, globalum auf Objekte im globalen Kontext zuzugreifen

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

oder verwenden jest.spyOnhinzugefügt19.0.0

jest.spyOn(global.console, 'warn')
Andreas Köberle
quelle
2
Ja Leute, es funktioniert. Eine Sache ist jedoch, dass Sie die Bibliothek benötigen müssen, nachdem Sie global.console deklariert haben. Ich habe es falsch gemacht. Ich brauchte meine Bibliothek und erklärte danach global. Vielen Dank.
Errorpro
1
Interessant, wie dies nirgendwo auf der Website von Jest dokumentiert ist. Ich suche und kann nichts finden, was dies erklärt.
Leonardo
1
mit Typoskript: Fehler TS2322: Typ '{warn: Mock <{}>; } 'kann nicht dem Typ' Konsole 'zugewiesen werden.
Gerard Brull
8
nur damit es allen bewusst ist. global.console = {...}wird den Fehler unterdrücken , während dies jest.spyOn(...)nicht der Fall ist. Sie entscheiden, ob Fehler in Ihren Tests unterdrückt werden sollen oder nicht.
a11smiles
37
Ich bevorzuge es, jest.spyOn(...)weil es einfacher zu bereinigen ist und ich TypeScript verwende, aber auch Fehler in der Ausgabe unterdrücken wollte, wie @ a11smiles erwähnt. Also habe ich verwendet, jest.spyOn(global.console, "warn").mockImplementation(() => {})was verhindert, dass der Spion zum zugrunde liegendenconsole.warn
djskinner
67

Verwenden Sie jest.spyOn()und spy.mockRestore().

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

Die akzeptierte Antwort stellt das Original nicht wieder her console.warn()und "gefährdet" die anderen Tests in derselben Datei (wenn console.warn()sie in den anderen Tests oder im zu testenden Code verwendet wird).

Zu Ihrer Information: Wenn Sie console.warn = jest.fn()eine Testdatei verwenden, hat dies keine Auswirkungen auf andere Testdateien (z. B. wird console.warn auf den ursprünglichen Wert in den anderen Testdateien zurückgesetzt).

Hinweis: Sie können spy.mockRestore()inside afterEach()/ aufrufen afterAll(), um sicherzustellen, dass selbst wenn ein Test abstürzt, die anderen Tests aus derselben Datei nicht beeinträchtigt werden (z. B. wird sichergestellt, dass die Tests in derselben Datei vollständig isoliert sind).

Vollständiges Beispiel:

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

Sie können nicht schreiben, console.warn = jest.fn().mockImplementation() [...] console.warn.mockRestore()da das Original nicht wiederhergestellt wird console.warn().

/! \ Mit müssen mockImplementationOnce()Sie noch anrufen 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

Sie können auch schreiben:

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