An integration test checks that multiple modules work together. For an Order service, a useful boundary is the database adapter and a running MySQL database: the test verifies behavior that an isolated adapter test cannot, including whether code still works after an adapter or database-version change. section 7.3
Choose the test level to match the behavior at risk:
- Use unit tests for an isolated component with mocked dependencies. They are generally faster and cheaper, so they form the largest part of the testing pyramid. section 7.1
- Use integration tests when the interaction itself matters, such as an adapter talking to a real database. Starting dependent components adds execution time and resource cost. section 7.1 section 7.3
- Use end-to-end tests for behavior across the full application flow, rather than treating a two-module test as proof that every service works together. section 7.1 section 7.6
For a Go database-adapter test, use Testcontainers to start MySQL, wait until it accepts SQL connections, and pass its connection URL to the adapter. Put shared setup in a test suite, run the suite with suite.Run, and execute the tests with go test ./.... Suite setup and teardown provide places to create required components and destroy them afterward. section 7.3.2 section 7.6
Order persistence against MySQL
Create an order with customer ID 2, save it through the database adapter, then retrieve it by order ID. Assert that the retrieved order has customer ID 2. A separate save test checks that the adapter returns no error. Because these calls reach the containerized MySQL instance, they test the adapter–database interaction rather than a mocked dependency. section 7.3.2 section 7.3






























