我正在使用 create-react-app 并尝试编写一个 jest 测试来检查
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.
如果您想检查
console.log
是否收到了正确的参数(您传入的参数),您应该检查 mock
的 jest.fn()
。log
函数,否则 console.log
永远不会被调用:
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');
});
或
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');
});
如果您采用这种方法,请不要忘记恢复
console.log
的原始值。
另一种选择是使用
jest.spyOn
(而不是替换 console.log
,它将创建一个代理):
it('console.log the text "hello"', () => {
const logSpy = jest.spyOn(console, 'log');
console.log('hello');
expect(logSpy).toHaveBeenCalledWith('hello');
});
阅读更多这里。
或者你可以这样做:
it('calls console.log with "hello"', () => {
const consoleSpy = jest.spyOn(console, 'log');
console.log('hello');
expect(consoleSpy).toHaveBeenCalledWith('hello');
});
另一种选择是保存对原始日志的引用,为每个测试替换为玩笑模拟,并在所有测试完成后恢复。这对于不污染测试输出并且仍然能够使用原始日志方法进行调试有一点好处。
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
});
});
我会考虑 toHaveBeenCalledWith 或 jest 提供的用于检查模拟调用的任何其他方法(以 toHaveBeenCalled 开头的方法)。
it('console.log the text "hello"', () => {
console.log = jest.fn();
log('hello');
expect(console.log).toHaveBeenCalledWith('hello');
});
如果您使用多个参数调用
console.log
,例如 `console.log('hi', ob1, obj2);
但只想测试字符串:
const logSpy = jest.spyOn(console, 'log');
const wasCalledWithTokenError = logSpy.mock.calls.some(call =>
call.some(arg => typeof arg === 'string' && arg.includes('invalid csrf token'))
);
expect(wasCalledWithTokenError).toBeTruthy();