Testing REST APIs

1. Writing Unit Tests

ScopeTools
Controller logic (mock services)JUnit + Mockito, pytest, Jest
Validation rulesBean Validation tests
Serialization/mappingJackson tests, MapStruct verification
Pure functionsFast, no I/O

2. Writing Integration Tests

Example: Spring MockMvc Integration Test

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIT {
    @Autowired MockMvc mvc;

    @Test
    void createUser_returns201() throws Exception {
        mvc.perform(post("/users")
                .contentType("application/json")
                .content("{\"name\":\"Alice\",\"email\":\"a@x.com\"}"))
           .andExpect(status().isCreated())
           .andExpect(header().exists("Location"))
           .andExpect(jsonPath("$.email").value("a@x.com"));
    }
}

3. Testing Authentication and Authorization

Test CaseExpected
No token401
Invalid/expired token401
Valid token, wrong role403
Valid token, correct role2xx
Token for different user accessing private resource403/404

4. Testing Error Handling

ScenarioVerify
Invalid JSON body400 + error structure
Missing required field422 + field-level errors
Resource not found404
Database failure500 + no stack trace leak

5. Testing Rate Limiting Behavior

Example: Rate Limit Test

@Test
void rateLimitReturns429AfterThreshold() {
    for (int i = 0; i < 100; i++) {
        api.get("/users").assertStatus(200);
    }
    api.get("/users")
       .assertStatus(429)
       .assertHeader("Retry-After")
       .assertHeader("X-RateLimit-Remaining", "0");
}

6. Testing Pagination and Filtering

TestVerify
Default page sizeReturns N items
page=2Returns next slice, no overlap
Empty page200 + empty array (not 404)
Filter combinationsAND logic, correct subset
Invalid filter field400

7. Using API Testing Tools

ToolStrength
Postman / BrunoManual testing, collections
REST AssuredJava DSL for API tests
SupertestNode.js HTTP assertions
HTTPie / curlCLI exploration
SchemathesisProperty-based from OpenAPI
KarateBDD API tests

8. Implementing Contract Testing

ToolApproach
PactConsumer-driven contracts
Spring Cloud ContractProducer-driven
OpenAPI + SchemathesisSpec-as-contract testing
GoalDetect breaking changes before deploy

9. Testing Idempotency Behavior

TestExpected
POST + Idempotency-Key, called twiceSame response, single side effect
Same key, different body422
PUT same body twiceSame final state
DELETE twice204 + 404 (or 204+204)

10. Load Testing

ToolUse
k6JS scripts, modern UX
JMeterGUI, mature
GatlingScala DSL, high throughput
LocustPython, distributed
wrk / heyLightweight CLI

11. Testing CORS Configuration

TestVerify Header
OPTIONS preflightAllow-Origin, Allow-Methods, Allow-Headers
Disallowed originNo Allow-Origin → browser blocks
Credentials requestAllow-Credentials: true + specific origin

12. Implementing Automated API Tests

StageTests Run
Pre-commitLint, unit tests
PR buildUnit + integration + contract
Pre-deployE2E smoke tests
Post-deploySynthetic monitoring, canary
NightlyLoad tests, security scans