liveBook · Manning

Fake logger

As explained in The Art of Unit Testing 3e

A lightweight logger test double that records supplied messages in accessible state instead of writing them to a real logging destination.

A fake logger is a lightweight test double that replaces a real logger and records messages in accessible state for later assertions. It avoids writing to real destinations while preserving the logger’s expected method, such as info. section 4.7.1 section 4.7.2

A fake logger is useful because it:

  • Receives the logger dependency through constructor injection instead of forcing production code to use a real logger. section 4.7.1
  • Stores the supplied message in a public field, allowing a test to assert what was logged. section 4.7.1 section 4.7.2
  • Can be reused as a stub or mock object, so the broader name fake avoids tying the class to one test role. section 4.7.1
  • Can implement an ILogger interface when production code is designed for a replaceable logger rather than a hard dependency on SimpleLogger. section 4.7.2

Checking a recorded message

Create a FakeLogger, inject it into PasswordVerifier, run verify, and assert that mockLog.logged matches PASSED. The fake records the interaction without requiring the real logging destination. section 4.7.1

Listing 4.11 Class-based constructor injection
class PasswordVerifier {
  _rules;
  _logger;
 
  constructor(rules, logger) {
    this._rules = rules;
    this._logger = logger;
  }
 
  verify(input) {
    const failed = this._rules
        .map(rule => rule(input))
        .filter(result => result === false);
 
    if (failed.length === 0) {
      this._logger.info('PASSED');
      return true;
    }
    this._logger.info('FAIL');
    return false;
  }
}

See the production shape: PasswordVerifier receives rules and a logger through its constructor, then calls info with PASSED or FAIL. section 4.7.1

How The Art of Unit Testing 3e covers it

How deep it goes
Demonstrates handwritten classes, recorded fields, constructor injection, and interface injection, but not automated mock-generation tools.
Examples
Uses JavaScript FakeLogger.logged and TypeScript FakeLogger.written fields to capture info calls for assertions.
What it assumes
Assumes basic tests and object construction, while teaching logger replacement through constructor parameters, duck typing, and interfaces.
What you can do after
Build it from scratch by implementing the required logger method, injecting the fake, running behavior, and asserting its recorded message.
How it connects
Connects fake loggers with test doubles, stubs, mock objects, dependency injection, constructor injection, and interfaces.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Art of Unit Testing 3e. The section links point to the parts of the book it draws on.