liveBook · Manning

Interaction testing

As explained in The Art of Unit Testing 3e

A testing technique that verifies how a unit of work interacts with its outgoing dependencies, including the calls made and their parameters.

Interaction testing checks how a unit of work communicates with an outgoing dependency: which calls it makes and which parameters it sends. It targets the third kind of exit point—a call to a third-party function, module, object, or system—rather than only a returned value or a state change. section 4.0 section 4.10

Mocks make this boundary observable. A mock replaces an outgoing dependency and is asserted against; a stub supplies incoming data or behavior but is not verified. Stubs are waypoints toward the result, while mocks represent an exit point. section 4.1 section 4.10

Checking a logger call

A unit can receive a mock logger through a parameter: `function run(logger) { logger.info("started"); }`. The test invokes `run(loggerMock)` and verifies that `info` was called with `"started"`. The assertion checks the interaction with the dependency, not the logger's internal implementation. section 4.1 section 4.10

Use interaction testing deliberately:

  • Keep the test focused on an important outgoing interaction, usually with no more than one mock. section 4.1 section 5.6.5
  • Prefer stubs when you only need to provide simulated values or exceptions; do not verify calls made to them. section 5.6.5
  • Inject mocks through parameters, factory or partial-application functions, module abstraction, or objects and interfaces. section 4.10
  • Avoid expectations that merely record every internal call: excessive interaction assertions make tests fragile when implementation changes. section 5.6.5
Figure 4.1 On the left, an exit point that is implemented as invoking a dependency. On the right, the dependency provides indirect input or behavior and is not an exit point.
04-01

Use the figure to distinguish an outgoing call that forms an exit point from a dependency that supplies indirect input or behavior. section 4.1

How The Art of Unit Testing 3e covers it

How deep it goes
Defines mocks, stubs, exit points, injection approaches, and overspecification trade-offs without detailing framework internals.
Examples
Uses a logger call, mock assertions, dependency injection variants, and expectations that become fragile through overspecification.
What it assumes
Assumes unit isolation and dependency doubles, while distinguishing incoming stubs from outgoing mocks.
What you can do after
Diagnose dependency-boundary behavior by injecting mocks and verifying important calls with their parameters.
How it connects
Connects mocks, stubs, dependency injection, exit points, isolation frameworks, and partial mocks.

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.