liveBook · Manning

Integration test

As explained in Unit Testing Principles, Practices, and Patterns

An integration test is a software test that verifies interactions and cooperation between integrated components or subsystems.

An integration test verifies how multiple parts of a system cooperate, typically by exercising application code together with out-of-process dependencies such as a database or message bus. Under the classical definition, any test that fails to verify one behavior quickly and in isolation from other tests is an integration test. section 2.4 section 8.1

Use integration tests selectively because they trade speed and maintainability for broader system-level protection:

  • Cover controllers and the code that connects the domain model to external systems; cover algorithms and domain behavior primarily with unit tests. section 8.1
  • Use the longest happy path that passes through all relevant out-of-process dependencies, plus edge cases that unit tests cannot exercise. section 8.3
  • Use real managed dependencies, such as an application database, and replace unmanaged dependencies, such as a message bus, with mocks. section 8.8
  • Keep integration tests fewer than unit tests in most systems: they provide stronger regression protection and refactoring resistance but slower feedback and higher maintenance cost. section 4.5 section 8.8
  • Verify unmanaged-dependency interactions at the system’s edges, mock only adapters you own, and check both expected and unexpected calls. section 9.3

Changing a customer email

A CRM controller retrieves a user and company from the database, changes a corporate email to a non-corporate address, saves both records, and emits an event. The integration test inserts the initial records into a real database, substitutes the message bus with a mock, invokes the controller, checks the successful result and persisted email, and verifies the outgoing message. This single test covers the longest happy path because it exercises every external dependency involved in the operation. section 8.3

Figure 2.6. End-to-end tests normally include all or almost all out-of-process dependencies in the scope. Integration tests check only one or two such dependencies—those that are easier to set up automatically, such as the database or the file system.

Compare integration-test scope with end-to-end scope: integration tests usually include only one or two automatically manageable out-of-process dependencies, while end-to-end tests include nearly all of them. section 2.4

How Unit Testing Principles, Practices, and Patterns covers it

How deep it goes
Explains definitions, dependency categorization, scenario selection, mocking boundaries, and a complete database-backed example.
Examples
Uses a CRM email-change workflow with a real database, mocked message bus, persisted state, and verified outgoing message.
What it assumes
Assumes unit-test distinctions and basic object-oriented design, while defining managed dependencies, unmanaged dependencies, and testing boundaries explicitly.
What you can do after
Apply it by selecting high-value system scenarios, using real managed dependencies, mocking unmanaged ones, and asserting observable outcomes.
How it connects
Connects unit testing, end-to-end testing, the Test Pyramid, controllers, domain models, databases, message buses, mocks, and the Fail Fast principle.

Also explained in

Compare how 31 books explain integration test →

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.