Detecting console.log() calls

爱⌒轻易说出口 提交于 2019-11-30 07:25:34

console.log doesn't keep a record of messages that are logged, or emit any events that you could listen for. It's not possible for your tests to directly verify its output from JavaScript. Instead, your test code will need to replace console.log with a mock implementation that does keep track of log messages for later verification.

Mocking is a common feature supported by most JavaScript test frameworks. For example, the Jest test framework provides a jest.spyOn function which replaces a given method with a mock implementation that records the arguments for each call in a .mock property before passing them on to the original implementation. After each test you may want to call jest.clearAllMocks() to reset the recorded argument lists for the next test, or use the equivalent clearMocks: true config option.

function saySomething() {
  console.log("Hello World");
}
jest.spyOn(console, 'log');

test("saySomething says hello", () => {
  expect(console.log.mock.calls.length).toBe(0);
  saySomething();
  expect(console.log.mock.calls.length).toBe(1);
  expect(console.log.mock.calls[0][0]).toBe("Hello World");
});

afterEach(() => {
  jest.clearAllMocks();
});

If you're not using a test framework (you probably should), you can create a simple mock yourself.

function saySomething() {
  console.log("Hello World");
}
function testSomething() {
  // Replace console.log with stub implementation.
  const originalLog = console.log;
  const calls = [];
  console.log = (...args) => {
    calls.push(args);
    originalLog(...args);
  };

  try {
    console.assert(calls.length == 0);
    saySomething();
    console.assert(calls.length == 1);
    console.assert(calls[0][0] == "Hello World");
  } catch (error) {
    console.error(error);
  } finally {
    // Restore original implementation after testing.
    console.log = originalLog;
  }
}

So not bad solutions, but if you're looking for a high powered logger try Paul Irish's log()

If that's too high powered, you can get by with something like this.

var console = window.console,
    _log = console ? console.log : function(){};

_log.history = [];

console.log = function( ){
  _log.history.push.apply( _log.history, arguments );
  _log.apply( console, arguments );
}

Usage

console.log('I','have','an','important','message');
//Use native one instead
_log.call( console, _log.history );

http://jsfiddle.net/BeXdM/

If you're using Jasmine, it's dead simple:

it('is my test', function () {
    spyOn(console, 'log');
    // do your stuff that should log something
    expect(console.log).toHaveBeenCalledWith('something');
});

Head to Jasmine docs for more info.

Just attach your own function to console.log. On your page, after everything loads,

Before starting tests -


var originalLog = console.log;
console.log = function(msg){
  alert('my .log hook received message - '+msg); 
  //add your logic here
}

After running tests, if necessary -

console.log = originalLog
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!