Testing Stubbed Functionality in Code

bob.ts - Jan 3 '22 - - Dev Community

One of the first things I do when writing Unit Tests is to stub out console.debug and console.log. I do this on the off chance that I leave one in the code. This way, there aren't extraneous console's showing in the terminal when the tests are run.

Don't get me wrong. I do not do this to be lazy. I take good care of my code and generally do not leave console.log all over the place. I use this code to keep things clean in the display, pure and simple.

Pure and simple that is until I realized that I had a new case for a slightly improved form of my stubbed-code.

Original Code

Here is the original code in the helper.ts file ...

beforeAll(() => {
  spyOn(console, 'debug').and.stub();
  spyOn(console, 'log').and.stub();
});
Enter fullscreen mode Exit fullscreen mode

As you can see there is nothing more done here than stubbing out the two console options.

In karma.conf.js, this is included ...

module.exports = function (config) {
  config.set({
    ...
    files: [
      'src/app/shared/_spec-tools/helper.js'
    ],
    ...
  });
};
Enter fullscreen mode Exit fullscreen mode

Handling Code

I mentioned in the title, handling console while testing and the code below is a simple endpoint for code I intend to write as this function gets fully fleshed out (it's a stub, conceptually ... not a Unit Test sub). I am generating the visuals that will eventually be used, but there is no backend to connect to at this point in time.

I am using console.log in this case to ensure I understand the values passed in and available that I intend to use some time in the future.

handleFunctionality = (note: string): void => {
  console.log(note, this.state);
};
Enter fullscreen mode Exit fullscreen mode

At the same time ...

  1. I don't want this code displaying a console.log every time tests are run.
  2. I do want a Unit Test against this function so that when I do change the code, this test will fail "spectacularly" as Test Driven Development says it should.

Improved Code

So, here's the code that ensures the stubs are in place AND calls are reset after each test is run.

let consoleDebug;
let consoleLog;

beforeAll(() => {
  consoleDebug = spyOn(console, 'debug');
  consoleDebug.and.stub();

  consoleLog = spyOn(console, 'log');
  consoleLog.and.stub();
});

afterEach(() => {
  consoleDebug.calls.reset();
  consoleLog.calls.reset();
});
Enter fullscreen mode Exit fullscreen mode

Summary

  1. I've always blocked console.log when my Unit Tests run.
  2. This scenario showed me that the Unit Tests can be used to ensure the "stubbed" code will break the tests when the real functionality gets put in place.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .