liveBook · Manning

Unmanaged dependency

As explained in Unit Testing Principles, Practices, and Patterns

An unmanaged dependency is an out-of-process dependency whose interactions are observable by external systems and that is not fully controlled by the application.

An unmanaged dependency is an out-of-process dependency that the application does not fully control and whose interactions are externally observable. SMTP servers and message buses are typical examples: their side effects can be seen by other applications, so their communication forms part of the system’s observable behavior. section 8.2

Classify each out-of-process dependency before choosing how an integration test should handle it:

  • Replace an unmanaged dependency with a mock, preserving and checking the communication pattern that external systems rely on. section 8.2
  • Use a real managed dependency, such as an application-only database, and verify its final state rather than its interactions. section 8.2
  • Split mixed dependencies by visibility: mock the externally visible portion of a database and verify the remainder through final-state assertions. section 8.8
  • Mock only the last type at the system edge, where the application’s adapter communicates with the external dependency; this protects the external contract without coupling tests to intermediate wrappers. section 9.1 section 9.3

Changing a user’s email

An integration test inserts a user and company into a real database, runs the change-email scenario, verifies the database state, and replaces the message bus with a test double. A stronger version constructs the production message-bus adapter around a mocked IBus, then verifies the exact emitted message once. A handwritten BusSpy can make the assertion shorter and more readable. section 8.3 section 9.1

Figure 8.4. Communications with managed dependencies are implementation details; use such dependencies as-is in integration tests. Communications with unmanaged dependencies are part of your system’s observable behavior. Such dependencies should be mocked out.

Use the dependency boundary to distinguish implementation details from externally observable communication. section 8.2

Figure 8.5. Treat the part of the database that is visible to external applications as an unmanaged dependency. Replace it with mocks in integration tests. Treat the rest of the database as a managed dependency. Verify its final state, not interactions with it.

Apply separate treatment when only part of a database is visible to external applications. section 8.2

How Unit Testing Principles, Practices, and Patterns covers it

How deep it goes
Defines the classification, prescribes mock or real-instance treatment, and extends the rule to mixed databases and system-edge adapters.
Examples
Uses SMTP servers, message buses, a partly visible database, and a change-email integration test with a message-bus mock or spy.
What it assumes
Assumes out-of-process dependencies and integration tests, while teaching the managed-versus-unmanaged distinction from its observable effects.
What you can do after
Apply it via integration tests by mocking external contracts, using real managed dependencies, and verifying interactions at system edges.
How it connects
Connects unmanaged dependencies to integration testing, managed dependencies, mocks, spies, interfaces, message buses, databases, and end-to-end 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.