Mocking

Version 1.1 by chrisby on 2023/05/29 11:37

Purpose

  • Mocking simplifies unit testing by replacing the dependencies of the unit being tested with simplified, simulated versions called mocks.
  • Example: Consider a unit under test that relies on a database. In testing, the database can be mocked to return a static value, eliminating the need for an actual database.

Benefits of Mocking

  • Isolation of units to test each unit separately, dramatically reducing complexity and increasing test execution speed by replacing loaded modules with mocks.
  • Simplifies the re-creation of specific scenarios (use cases, boundary cases).
  • Expose hidden internals of production code without compromising encapsulation.
  • Injection of test-specific behaviors not present in production code.
  • Enables the simulation of indirect dependencies by letting mocks return other mocks.

Types of Mocks

Stubs are by far the most common type of mock. Keep your tests as simple as possible. Make them more complex only when necessary.

  • Stubs: Simplest form, returning a hardcoded value or providing an empty method body.
  • Fake object: Include minimal logic to handle different case scenarios.
  • Spy: Injected to capture interaction data with fake objects when such data is not directly accessible.
  • Mock objects: Contain complex logic, simulate behaviors such as computation and exception handling, and even run tests.

Tips

  • Mock third-party libraries for unit tests to ensure proper unit functionality. Instead, use the third-party libraries in component and integration tests.
  • Minimize the dependencies of a unit. The fewer dependencies, the easier it is to mock and test the logic.
    • If a class has too many dependencies, split the class or extract two dependencies into a new class. This also results in smaller, more cohesive classes/units.
    • If there is more than one test class for a production class, the production class is probably too large.
    • If the test code is very complex and hard to understand, the production class is probably too large.