Jest: modo migliore per disabilitare la console all'interno degli unit test


103

Mi chiedo se ci sia un modo migliore per disabilitare gli errori della console all'interno di uno specifico test Jest (cioè, ripristinare la console originale prima / dopo ogni test).

Ecco il mio approccio attuale:

describe("Some description", () => {
  let consoleSpy;

  beforeEach(() => {
    if (typeof consoleSpy === "function") {
      consoleSpy.mockRestore();
    }
  });

  test("Some test that should not output errors to jest console", () => {
    expect.assertions(2);

    consoleSpy = jest.spyOn(console, "error").mockImplementation();

    // some function that uses console error
    expect(someFunction).toBe("X");
    expect(consoleSpy).toHaveBeenCalled();
  });

  test("Test that has console available", () => {
    // shows up during jest watch test, just as intended
    console.error("test");
  });
});

Esiste un modo più pulito per ottenere la stessa cosa? Vorrei evitare spyOn, ma mockRestoresembra funzionare solo con esso .

Grazie!

Risposte:


136

Per file di specifiche particolari, quello di Andreas è abbastanza buono. La seguente configurazione sopprimerà le console.logistruzioni per tutte le suite di test,

jest --silent

(o)

Per personalizzare warn, info and debugè possibile utilizzare l'impostazione di seguito

__tests __ / setup.js o jest-preload.js configurato insetupFilesAfterEnv

global.console = {
  log: jest.fn(), // console.log are ignored in tests

  // Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log`
  error: console.error,
  warn: console.warn,
  info: console.info,
  debug: console.debug,
};

jest.config.js

module.exports = {
    verbose: true,
    setupTestFrameworkScriptFile: "<rootDir>/__tests__/setup.js",
};

Jest v24.x Nota: setupTestFrameworkScriptFile è deprecato a favore di setupFilesAfterEnv.

module.exports = {
    verbose: true,
    setupFilesAfterEnv: ["<rootDir>/__tests__/setup.js"],
};

2
Ciao! setupTestFrameworkScriptFileè deprecato a favore di setupFilesAfterEnv.
elhoucine

1
La derisione global.consoleè davvero un modo semplice per andare e può essere eseguita tramite qualsiasi configurazione setupFilesAfterEnv . Attenzione a deridere tutti i metodi nativi consoledell'oggetto o potresti incontrare altri errori imprevisti.
Vadorequest

53

Poiché ogni file di test viene eseguito nel proprio thread, non è necessario ripristinarlo se si desidera disabilitarlo per tutti i test in un file. Per lo stesso motivo puoi anche scrivere

console.log = jest.fn()
expect(console.log).toHaveBeenCalled();

1
Grazie per le informazioni su questo argomento. Ha senso :) Stavo cercando un modo per farlo in quel modo solo all'interno di un test specifico senza doverlo ripristinare (inizialmente pensavo che fosse il comportamento predefinito), ma immagino prima che ognuno faccia il trucco.
Apidcloud

51

Se vuoi farlo solo per un test specifico:

beforeEach(() => {
  jest.spyOn(console, 'warn').mockImplementation(() => {});
});

1
è brillante!
sheriff_paul

21

Ho trovato che la risposta sopra re: sopprimere console.login tutte le suite di test ha gettato errori quando tutti gli altri consolemetodi (ad esempio warn, error) sono stati chiamati da quando è stato sostituire l'intero globale consoleoggetto.

Questo approccio in qualche modo simile ha funzionato per me con Jest 22+:

package.json

"jest": {
  "setupFiles": [...],
  "setupTestFrameworkScriptFile": "<rootDir>/jest/setup.js",
  ...
}

jest / setup.js

jest.spyOn(global.console, 'log').mockImplementation(() => jest.fn());

Utilizzando questo metodo, solo console.logviene deriso e altri consolemetodi non vengono modificati.


7

Per me un modo più chiaro / pulito (il lettore ha bisogno di poca conoscenza dell'API jest per capire cosa sta succedendo), è semplicemente fare manualmente ciò che fa mockRestore:

// at start of test you want to suppress
const consoleLog = console.log;
console.log = jest.fn();

// at end of test
console.log = consoleLog;

1
Devi anche coprire console.info, console.error, console.warn, ecc.
Michael Oryl

1
@ michael-liquori perché devi riavviare console.log? Penso che dopo ogni descrizione le prese in giro siano cancellate
Jhonatan

2
@ Jhonatan Non credo che sia chiaro dopo ogni descrizione, anche se non l'ho provato di recente per esserne sicuro. Secondo documenti jest c'è clearMockse resetMocksconfigurazione delle opzioni ma entrambi predefinito false, e nessuno di quelli effettivamente ripristinare l'implementazione iniziale anche se impostata a true. E, considerando che questa è un'opzione di configurazione che potrebbe essere modificata a un certo punto, penso che sia la migliore pratica pulire manualmente per garantire che i tuoi test non causino problemi in futuro.
Michael Liquori

0

Un altro approccio è usare process.env.NODE_ENV. In questo modo si può scegliere selettivamente cosa mostrare (o meno) durante l'esecuzione dei test:

if (process.env.NODE_ENV === 'development') {
  console.log('Show output only while in "development" mode');
} else if (process.env.NODE_ENV === 'test') {
  console.log('Show output only while in "test" mode');
}

o

const logDev = msg => {
  if (process.env.NODE_ENV === 'development') {
    console.log(msg);
  }
}
logDev('Show output only while in "development" mode');

Ciò richiederà che questa configurazione sia posizionata su package.json:

"jest": {
  "globals": {
    "NODE_ENV": "test"
  }
}

Si noti che questo approccio non è una soluzione diretta alla domanda originale, ma fornisce il risultato atteso fintanto che si ha la possibilità di avvolgere il console.logcon la condizione menzionata.


1
Quello che l'autore della domanda è come disabilitare console.log durante i test. Questa soluzione non è ottimale.
Erick

Per i copy-pasters là fuori: sostituisci ===con !==secondo le tue esigenze. Uso questo approccio da anni e funziona perfettamente, ma apporto le modifiche in base alle mie esigenze.
Wallace Sidhrée

Non risponde alla domanda effettiva.
Michael Oryl

Questa è una soluzione hacky e non personalizzabile. Cosa succede se disabilitare solo per un test specifico e non per l'altro?
Jhonatan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.