Integration testing with Redis
The library includes integration tests using Testcontainers to verify behavior against a real Redis instance.Example: Basic rate limiting test
Fromredis/RedisRateLimiterIT.java:57-71:
- Starts a Redis container using Testcontainers
- Creates a rate limiter with a limit of 2 requests per minute
- Makes 3 requests and verifies the 3rd is blocked
Example: Concurrent access test
Fromredis/RedisRateLimiterIT.java:73-118:
Unit testing with mocks
Unit tests use mocked dependencies to test rate limiting logic in isolation.Example: Allowed request test
Fromredis/RedisRateLimiterTest.java:42-56:
Example: Blocked request test
Fromredis/RedisRateLimiterTest.java:58-70:
Example: Error handling test
Fromredis/RedisRateLimiterTest.java:84-98:
Testing Spring Boot controllers
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
class RateLimitIntegrationTest {
@Autowired
private MockMvc mockMvc;
}
@Test
void shouldRateLimitRequests() throws Exception {
String endpoint = "/api/data";
int limit = 10;
// Make requests up to the limit
for (int i = 0; i < limit; i++) {
mockMvc.perform(get(endpoint))
.andExpect(status().isOk());
}
// Next request should be blocked
mockMvc.perform(get(endpoint))
.andExpect(status().isTooManyRequests())
.andExpect(jsonPath("$.title").value("Rate limit exceeded"))
.andExpect(header().exists("Retry-After"));
}
@Test
void shouldIsolateLimitsByScope() throws Exception {
// Exhaust limit for user 1
for (int i = 0; i < 10; i++) {
mockMvc.perform(get("/api/data")
.header("X-User-Id", "user1"))
.andExpect(status().isOk());
}
// User 1 should be rate limited
mockMvc.perform(get("/api/data")
.header("X-User-Id", "user1"))
.andExpect(status().isTooManyRequests());
// User 2 should still be allowed
mockMvc.perform(get("/api/data")
.header("X-User-Id", "user2"))
.andExpect(status().isOk());
}
@Test
void shouldResetAfterWindow() throws Exception {
String endpoint = "/api/data";
// Exhaust the limit
for (int i = 0; i < 10; i++) {
mockMvc.perform(get(endpoint))
.andExpect(status().isOk());
}
// Should be blocked
mockMvc.perform(get(endpoint))
.andExpect(status().isTooManyRequests());
// Wait for window to expire (assuming 1 minute window)
Thread.sleep(61_000);
// Should be allowed again
mockMvc.perform(get(endpoint))
.andExpect(status().isOk());
}