Jest: Konsol içi birim testlerini devre dışı bırakmanın daha iyi yolu


91

Daha iyi bir yolu olup olmadığını merak devre dışı konsol hataları içindeki bir belirli Jest testi (yani orijinal konsolu geri her testten sonra / 'önce).

İşte şu anki yaklaşımım:

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");
  });
});

Aynı şeyi başarmanın daha temiz bir yolu var mı? Kaçınmak isterdim spyOnama mockRestoresadece bununla çalışıyor gibi görünüyor .

Teşekkürler!

Yanıtlar:


126

Belirli bir özellik dosyası için Andreas'ınki yeterince iyidir. Aşağıdaki kurulum, console.logtüm test paketleri için ifadeleri bastıracaktır ,

jest --silent

(veya)

Özelleştirmek warn, info and debugiçin aşağıdaki kurulumu kullanabilirsiniz

__testler __ / setup.js veya jest-preload.js yapılandırılmışsetupFilesAfterEnv

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 Not: setupTestFrameworkScriptFile, setupFilesAfterEnv lehine kullanımdan kaldırılmıştır.

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

2
Selam! setupTestFrameworkScriptFilelehine kullanımdan kaldırıldı setupFilesAfterEnv.
elhoucine

1
Alay global.consoleetmek gerçekten de basit bir yoldur ve herhangi bir yapılandırmayla yapılabilir setupFilesAfterEnv . consoleNesnenin tüm yerel yöntemleriyle dalga geçmeye dikkat edin, aksi takdirde diğer beklenmedik hatalarla karşılaşabilirsiniz.
Vadorequest

49

Her test dosyası kendi iş parçacığında çalıştığından, tek bir dosyadaki tüm testler için devre dışı bırakmak istiyorsanız geri yüklemenize gerek yoktur. Aynı sebepten dolayı sadece yazabilirsin

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

1
Bu konudaki bilgi için teşekkür ederim. Mantıklı geliyor :) Sadece belirli bir testte onu geri yüklemek zorunda kalmadan bu şekilde yapmanın bir yolunu arıyordum (başlangıçta bunun varsayılan olarak davranış olduğunu düşündüm), ama sanırım her hile yapmadan önce.
Apidcloud

46

Bunu sadece belirli bir test için yapmak istiyorsanız:

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

1
bu harika!
sheriff_paul

20

Bastırmak: Ben yeniden yukarıdaki cevabı bulundu console.logbaşka zaman tüm test suit genelinde hataları attı consoleyöntemleri (örn warn, erroro tüm küresel değiştirilmesi beri) denirdi consolenesne.

Bu biraz benzer yaklaşım, Jest 22+ ile benim için çalıştı:

package.json

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

jest / setup.js

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

Bu yöntemi kullanarak, yalnızca console.logalay edilir ve diğer consoleyöntemler etkilenmez.


6

Benim için daha net / temiz bir yol (okuyucunun, neler olduğunu anlamak için jest API'sine dair çok az bilgiye ihtiyacı var), mockRestore'un yaptığı şeyi sadece manuel olarak yapmaktır:

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

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

1
Ayrıca console.info, console.error, console.warn, vb.
De dahil etmeniz gerekir

1
@ michael-liquori neden console.log'u yeniden başlatmanız gerekiyor? Sanırım her tanımlamadan sonra
taklitler

2
@Jhonatan Her tanımlamadan sonra net olduğunu sanmıyorum, ancak emin olmak için son zamanlarda bunu test etmedim. Göre jest dokümanlar bir olduğunu clearMocksve resetMocksyapılandırma seçeneği ama ikisi de varsayılan etmek false, ve ne olanların aslında bile seti için ilk uygulamasını geri true. Ve bunun bir noktada değiştirilebilecek bir yapılandırma seçeneği olduğunu düşünürsek, testlerinizin gelecekte sorunlara neden olmayacağından emin olmak için manuel olarak temizlemenin en iyi uygulama olduğunu düşünüyorum.
Michael Liquori

-1

Başka bir yaklaşım kullanmaktır process.env.NODE_ENV. Bu şekilde, testleri çalıştırırken neyin gösterileceğini (veya gösterilmeyeceğini) seçerek seçebilirsiniz:

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');
}

veya

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

Bu, bu yapılandırmanın aşağıdakilere yerleştirilmesini gerektirecektir package.json:

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

Bu yaklaşımın asıl soruya doğrudan bir çözüm olmadığını, ancak console.logsöz konusu durumla başa çıkma imkanı olduğu sürece beklenen sonucu verdiğini unutmayın .


1
Sorunun yazarı, test sırasında console.log'un nasıl devre dışı bırakılacağıdır. Bu çözüm optimal değil.
Erick

Orada kopyalamaya karşı pasters için: değiştirmek ===ile !==ihtiyaçlarınıza göre. Bu yaklaşımı yıllardır kullanıyorum ve kusursuz çalışıyor ama ihtiyaçlarıma göre ayarlamalar yapıyorum.
Wallace Sidhrée

Asıl soruya cevap vermiyor.
Michael Oryl

Bu karmaşık bir çözümdür ve özelleştirilemez. Ya yalnızca belirli bir test için devre dışı bırakılırsa diğeri için devre dışı bırakılırsa?
Jhonatan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.