Jest: วิธีที่ดีกว่าในการปิดใช้งานคอนโซลภายในการทดสอบหน่วย


103

ฉันสงสัยว่ามีวิธีที่ดีกว่าในการปิดใช้งานข้อผิดพลาดของคอนโซล ภายในการทดสอบ Jest เฉพาะหรือไม่ (เช่นคืนค่าคอนโซลเดิมก่อน / หลังการทดสอบแต่ละครั้ง)

นี่คือแนวทางปัจจุบันของฉัน:

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

มีวิธีที่สะอาดกว่าในการทำสิ่งเดียวกันนี้ให้สำเร็จหรือไม่? ฉันต้องการหลีกเลี่ยงspyOnแต่mockRestoreดูเหมือนจะใช้ได้กับมันเท่านั้น

ขอบคุณ!

คำตอบ:


135

สำหรับไฟล์ข้อมูลจำเพาะโดยเฉพาะ Andreas นั้นดีพอ การตั้งค่าด้านล่างนี้จะระงับconsole.logข้อความสำหรับชุดทดสอบทั้งหมด

jest --silent

(หรือ)

ในการปรับแต่งwarn, info and debugคุณสามารถใช้การตั้งค่าด้านล่าง

__tests __ / setup.js หรือ jest-preload.jsกำหนดค่าใน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 หมายเหตุ: setupTestFrameworkScriptFile เลิกใช้เพื่อสนับสนุน setupFilesAfterEnv

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

2
ไฮ! จะเลิกในความโปรดปรานของsetupTestFrameworkScriptFile setupFilesAfterEnv
elhoucine

1
Mocking ย่อมเป็นวิธีที่ง่ายที่จะไปและสามารถทำได้ผ่านการกำหนดค่าใดglobal.consolesetupFilesAfterEnv ระวังการล้อเลียนเมธอดดั้งเดิมทั้งหมดของconsoleอ็อบเจ็กต์มิฉะนั้นคุณอาจพบข้อผิดพลาดอื่น ๆ ที่ไม่คาดคิด
Vadorequest

53

เนื่องจากไฟล์ทดสอบทุกไฟล์ทำงานในเธรดของตัวเองจึงไม่จำเป็นต้องกู้คืนหากคุณต้องการปิดใช้งานสำหรับการทดสอบทั้งหมดในไฟล์เดียว ด้วยเหตุผลเดียวกันคุณสามารถเขียนได้

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

1
ขอบคุณสำหรับข้อมูลในเรื่องนั้น มันสมเหตุสมผล :) ฉันกำลังมองหาวิธีที่จะทำให้เป็นแบบนั้นภายในการทดสอบเฉพาะโดยไม่ต้องกู้คืน (ตอนแรกฉันคิดว่านั่นเป็นพฤติกรรมโดยค่าเริ่มต้น) แต่ฉันเดาว่าก่อนหน้านี้แต่ละคนทำเคล็ดลับ
Apidcloud


21

ผมพบว่าคำตอบข้างต้น Re: ปราบปรามconsole.logทั่วห้องทดสอบทั้งหมดโยนข้อผิดพลาดเมื่ออื่น ๆconsoleวิธีการ (เช่นwarn, error) ถูกเรียกว่าตั้งแต่มันถูกแทนที่ทั้งหมดทั่วโลกconsoleวัตถุ

วิธีการที่ค่อนข้างคล้ายกันนี้ใช้ได้กับฉันกับ Jest 22+:

package.json

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

jest / setup.js

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

ใช้วิธีนี้เท่านั้นconsole.logถูกล้อเลียนและconsoleวิธีอื่น ๆจะไม่ได้รับผลกระทบ


7

สำหรับฉันวิธีที่ชัดเจน / สะอาดมากขึ้น (ผู้อ่านต้องการความรู้เล็กน้อยเกี่ยวกับ jest API เพื่อทำความเข้าใจสิ่งที่เกิดขึ้น) คือทำสิ่งที่ 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
คุณต้องครอบคลุม console.info, console.error, console.warn ฯลฯ
Michael Oryl

1
@ michael-Liquori ทำไมคุณต้องรีสตาร์ท console.log? ฉันคิดว่าทุกครั้งหลังจากอธิบายเรื่องล้อเลียนเสร็จแล้ว
Jhonatan

2
@Jhonatan ฉันไม่คิดว่ามันจะชัดเจนหลังจากอธิบายทุกครั้งแม้ว่าฉันจะไม่ได้ทดสอบสิ่งนี้เมื่อเร็ว ๆ นี้เพื่อให้แน่ใจ ตามเอกสารตลกมีclearMocksและresetMocksการกำหนดค่าตัวเลือก แต่พวกเขาทั้งสองเริ่มต้นfalse, และtrueค่าของผู้ที่จริงเรียกคืนการดำเนินการเริ่มต้นแม้ว่าชุด และเมื่อพิจารณาว่านี่เป็นตัวเลือกการกำหนดค่าที่สามารถเปลี่ยนแปลงได้ในบางจุดฉันคิดว่าเป็นแนวทางปฏิบัติที่ดีที่สุดในการล้างข้อมูลด้วยตนเองเพื่อให้แน่ใจว่าการทดสอบของคุณจะไม่ก่อให้เกิดปัญหาในอนาคต
Michael Liquori

0

process.env.NODE_ENVอีกวิธีหนึ่งคือการใช้งาน วิธีนี้เราสามารถเลือกสิ่งที่จะแสดง (หรือไม่) ในขณะที่ทำการทดสอบ:

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

หรือ

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

สิ่งนี้จะต้องวางการกำหนดค่านี้ไว้ที่package.json:

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

โปรดทราบว่าวิธีนี้ไม่ใช่วิธีแก้ปัญหาโดยตรงสำหรับคำถามเดิม แต่ให้ผลลัพธ์ที่คาดหวังตราบเท่าที่มีความเป็นไปได้ที่จะรวมเข้าconsole.logกับเงื่อนไขที่กล่าวถึง


1
สิ่งที่ผู้เขียนคำถามคือวิธีปิดการใช้งาน console.log ในการทดสอบ วิธีนี้ไม่เหมาะสม
Erick

สำหรับการคัดลอกออกมี pasters: แทนที่===ด้วย!==ตามความต้องการของคุณ ฉันใช้แนวทางนี้มาหลายปีแล้วและได้ผลอย่างไม่มีที่ติ แต่ฉันปรับเปลี่ยนตามความต้องการของฉัน
Wallace Sidhrée

ไม่ตอบคำถามที่แท้จริง
Michael Oryl

นี่เป็นโซลูชันที่แฮ็กและไม่สามารถปรับแต่งได้ จะเกิดอะไรขึ้นหากปิดใช้งานสำหรับการทดสอบเฉพาะเท่านั้นไม่ใช่การทดสอบอื่น
Jhonatan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.