liveBook · Manning

Mutable shell

As explained in Unit Testing Principles, Practices, and Patterns

A mutable shell is the architectural part that handles state changes, side effects, and communication with external systems around a functional core.

A mutable shell handles state changes, side effects, and communication with external systems around a functional core. It gathers inputs, passes them to the core, and turns the core’s decisions into visible effects. section 6.3 section 6.6

Keep the shell deliberately small:

  • Gather external data without making additional business decisions. section 6.3
  • Give the functional core enough information to make complete decisions. section 6.3
  • Represent decisions explicitly as outputs such as file updates, commands, or messages. section 6.3 section 6.4
  • Apply those outputs through databases, filesystems, buses, or other external dependencies. section 6.3

Refactoring an audit system

A filesystem-bound AuditManager reads files, decides where a visitor record belongs, and writes the result itself. Refactoring moves the decision into a pure AuditManager that accepts FileContent values and returns a FileUpdate. Persister reads the directory and applies that update, while ApplicationService coordinates the read-decide-act sequence. The resulting test compares the returned FileUpdate directly instead of configuring a filesystem mock. section 6.4

The pattern improves testability and maintainability by concentrating complexity in output-driven business logic and leaving fewer integration tests around effects. It adds code and may reduce performance, so apply it when system complexity and importance justify the investment; do not pursue architectural purity at any cost. section 6.5 section 6.6

How Unit Testing Principles, Practices, and Patterns covers it

How deep it goes
Explains responsibilities, refactoring steps, test consequences, and trade-offs, but stops short of prescribing universal adoption.
Examples
Uses an audit filesystem, FileContent, FileUpdate, Persister, ApplicationService, mocks, and direct output assertions.
What it assumes
Assumes familiarity with side effects, external dependencies, and unit testing while clarifying functional cores and immutable inputs.
What you can do after
Build it from scratch by moving decisions into explicit outputs and retaining a thin shell for reading and applying effects.
How it connects
Connects functional core, functional architecture, hexagonal architecture, side effects, and output-based testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Unit Testing Principles, Practices, and Patterns. The section links point to the parts of the book it draws on.