API integration tests aren’t about checking 200 OK.
They exist to answer a harder question:
When a real request crosses authentication, validation, persistence, and transactions — does the system behave correctly?
Most production bugs don’t live inside a single function.
They happen between boundaries.
What Integration Tests Should Actually Prove
A useful API integration test verifies:
- routing + request parsing
- authentication & authorization
- validation and error shape
- database writes and reads
- transaction boundaries
- response contract
- retry / duplicate handling
- concurrency behavior
This sits between unit tests and end-to-end tests:
- Unit → logic correctness
- Integration → system behavior at boundaries
- E2E → full user journey
Start With Risk, Not Coverage
Don’t write the same number of tests per endpoint.
Focus on endpoints that:
- mutate important data
- cross auth or tenant boundaries
- involve multiple writes or transactions
- depend on external systems
- must handle retries or duplicates
- have broken in production before
The goal isn’t coverage.
It’s risk-weighted confidence.
What a Good Test Looks Like
A strong integration test:
- sends a real HTTP request
- goes through real auth + validation
- writes to a real database
- asserts persisted state, not just response
const res = await request(app)
.post('/api/orders')
.set('Authorization', `Bearer ${token}`)
.send(body)
expect(res.status).toBe(201)
const order = await db.order.findFirst(...)
expect(order).toBeTruthy()
If you only check the response, you’re missing half the system.
The Critical Cases People Skip
These are where integration tests provide real value:
- Authorization → tenant / ownership rules
- Validation → bad input blocked before writes
- Rollback → no partial state on failure
- Idempotency → retries don’t duplicate effects
- Concurrency → overlapping requests don’t break invariants
Most bugs hide here—not in the happy path.
What Not to Mock
Avoid mocking:
- database
- transactions
- auth middleware
- validation
- your own application code
Mock only external systems like payments or email.
Mock dependencies outside your system, not inside it.
The Short Version
Good API integration tests prove:
- real requests cross real boundaries
- correct state is persisted
- failures don’t leave partial data
- retries and concurrency are safe
- response contracts don’t break clients
They matter because production bugs usually live between components, not inside them.
👉 Full deep dive (idempotency, concurrency, rollback examples):
https://codenotes.tech/blog/how-to-write-api-integration-tests
Top comments (0)