liveBook · Manning

Behavior

As explained in Unit Testing Principles, Practices, and Patterns

Observable behavior is the externally detectable functionality and outcome produced by software.

Observable behavior is the externally detectable functionality or state that helps a client achieve a goal. Tests should verify what the system produces, not how it produces it. section 5.2 section 5.5

Observable behavior and implementation details form a separate dimension from public and private APIs. A public method can still expose an implementation detail, while private code can occasionally implement a non-public contract. section 5.2 section 11.8

Treat code as observable behavior when it does either of the following:

  • Expose an operation that helps the client achieve a goal, such as performing a calculation or causing a side effect. section 5.5
  • Expose state that helps the client achieve a goal, such as information that production code uses to determine an outcome. section 5.5
  • Keep implementation details private so the public API coincides with the behavior clients actually need. section 5.2

Normalize names without leaking the mechanism

A User class initially exposes NormalizeName, allowing clients and tests to depend on trimming and length limits directly. Moving normalization into the Name setter preserves the observable outcome while hiding the implementation detail.

Test the discount, not the status field

Customer.Promote changes private status from Regular to Preferred, but production code observes only the resulting discount. Test no discount before promotion and a 5% discount afterward. section 11.2

Extract complex hidden logic

When a private price calculation is too complex to test through Order’s observable behavior, extract it into PriceCalculator rather than making GetPrice public. section 11.1

Use observable behavior as a black-box boundary: test private methods and state indirectly, avoid granting tests special privileges, and widen the public API only when clients genuinely need the operation or state. section 11.1 section 11.8

How Unit Testing Principles, Practices, and Patterns covers it

How deep it goes
Defines observable operations and state, contrasts APIs, and demonstrates encapsulation and refactoring consequences.
Examples
Uses user-name normalization, customer discounts, private price calculation, and dog behavior to distinguish outcomes from internal steps.
What it assumes
Assumes familiarity with APIs, unit testing, and object-oriented code while distinguishing public visibility from observable purpose.
What you can do after
Apply it by writing black-box tests against client goals and refactoring leaked or overly complex implementation details.
How it connects
Connects observable behavior with implementation details, public API, private API, encapsulation, black-box testing, and refactoring.

Also explained in

Compare how 4 books explain behavior →

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.