如何测试 jest console.log

我正在使用 创建-反应-应用程序并尝试编写一个 开玩笑的测试来检查 console.log的输出。

我的测试功能是:

export const log = logMsg => console.log(logMsg);

我的测试是:

it('console.log the text "hello"', () => {
console.log = jest.fn('hello');
expect(logMsg).toBe('hello');
});

这是我的错误

 FAIL  src/utils/general.test.js
● console.log the text hello


expect(received).toBe(expected)    Expected value to be (using ===):      "hello"
Received:
undefined
Difference:
Comparing two different types of values. Expected string but received undefined.
104290 次浏览

If you want to check that console.log received the right parameter (the one that you passed in) you should check mock of your jest.fn().
You also have to invoke your log function, otherwise console.log is never invoked:

it('console.log the text "hello"', () => {
console.log = jest.fn();
log('hello');
// The first argument of the first call to the function was 'hello'
expect(console.log.mock.calls[0][0]).toBe('hello');
});

or

it('console.log the text "hello"', () => {
console.log = jest.fn();
log('hello');
// The first argument of the first call to the function was 'hello'
expect(console.log).toHaveBeenCalledWith('hello');
});

If you're going with this approach don't forget to restore the original value of console.log.

Another option is to use jest.spyOn (instead of replacing the console.log it will create a proxy to it):

it('console.log the text "hello"', () => {
const logSpy = jest.spyOn(console, 'log');


console.log('hello');


expect(logSpy).toHaveBeenCalledWith('hello');
});

Read more here.

I would consider toHaveBeenCalledWith or any other of the methods that jest offers for checking mock calls (the ones that start with toHaveBeenCalled).

it('console.log the text "hello"', () => {
console.log = jest.fn();
log('hello');
expect(console.log).toHaveBeenCalledWith('hello');
});

Or you could do it like this:

it('calls console.log with "hello"', () => {
const consoleSpy = jest.spyOn(console, 'log');


console.log('hello');


expect(consoleSpy).toHaveBeenCalledWith('hello');
});

Another option is to save off a reference to the original log, replace with a jest mock for each test, and restore after all the tests have finished. This has a slight benefit to not polluting the test output and still being able to use the original log method for debugging purposes.

describe("Some behavior that will log", () => {
const log = console.log; // save original console.log function
beforeEach(() => {
console.log = jest.fn(); // create a new mock function for each test
});
afterAll(() => {
console.log = log; // restore original console.log after all tests
});
test("no log", () => {
// TODO: test something that should not log
expect(console.log).not.toHaveBeenCalled();
});
test("some log", () => {
// TODO: execute something that should log
expect(console.log).toHaveBeenCalledWith(
expect.stringContaining("something")
);
const message = console.log.mock.calls[0][0]; // get actual log message
log(message); // actually log out what the mock was called with
});
});