Unit tests pass but the real API fails: how do you cover contracts missed by mocks?
If unit tests pass but the real API fails, compare mock responses against the actual contract, including fields, status codes and timeouts. An always-successful mock verifies only an idealized path.
Start troubleshooting here
If unit tests pass but the real API fails, compare mock responses against the actual contract, including fields, status codes and timeouts. An always-successful mock verifies only an idealized path. Constrain substitutes and check interactions in an authorized isolated environment instead of weakening assertions until tests pass.
Compare the real failing response with the test substitute
This applies to missing production fields, different error formats and timeouts never represented locally. Save a sanitized failed response and request shape and confirm the API version. Fixtures must retain behaviorally important fields and types; replacing every exception with an ordinary empty list does not establish real failure handling.
Check field types, errors and timeout behavior
Check whether mocks allow nonexistent methods or make arbitrary attributes succeed. Compare required fields, pagination and error responses and verify HTTP status handling. A timeout does not necessarily mean the service did nothing. For writes, inspect unknown-outcome and idempotency handling instead of treating every network error as permission to retry.
Constrain mocks with the contract and add isolated integration checks
Limit substitutes to the actual client interface and cover successful, missing-field and explicit-error branches. Add a small number of isolated integration tests using test accounts and requests without side effects to check serialization and authentication. Supply credentials through established secure configuration, never fixtures. Paid calls and business writes remain subject to existing authorization.
Verify that failures are handled and reported correctly
Check both normal output and clear propagation of errors to callers so exceptions cannot become false success. Compare shapes of mocked and actual test responses and confirm timeout paths do not unconditionally repeat writes. Report unit and integration results separately. Without contacting an actual test service, describe the result only as contract-fixture validation.
This article called no customer API or spent credits; it describes test layering. Contracts change, so preserved samples need version and date markers. Specifications cannot cover every network condition, requiring actual environment checks. Passing mocks do not establish integration, and one successful integration call does not replace error and permission checks.
Checked sources
These sources support the concepts and methods described here. Examples and test scope are labeled separately; check the version of the tools you use.