test(web): add edge case tests for interceptors
- Add inactive token test for UserAuthInterceptor (line 27) - Add 1xx status code test for ApiResponseWrapperInterceptor (line 31) - Add production profile and Redis null tests for RateLimitInterceptor Coverage improvement: Web package 83% -> 85% (92/108 branches) Overall: 66% (429/646 branches), +2 branches from previous commit
This commit is contained in:
@@ -200,4 +200,17 @@ class ApiResponseWrapperInterceptorTest {
|
||||
// Then
|
||||
verify(response, never()).setHeader(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("postHandle不应该为1xx信息响应设置版本头")
|
||||
void shouldNotSetVersionHeader_whenResponseIsInformational() {
|
||||
// Given - 100 Continue
|
||||
when(response.getStatus()).thenReturn(100);
|
||||
|
||||
// When
|
||||
interceptor.postHandle(request, response, handler, modelAndView);
|
||||
|
||||
// Then
|
||||
verify(response, never()).setHeader(anyString(), anyString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ class RateLimitInterceptorTest {
|
||||
Environment environment = mock(Environment.class);
|
||||
StringRedisTemplate redisTemplate = mock(StringRedisTemplate.class);
|
||||
ValueOperations<String, String> valueOperations = mock(ValueOperations.class);
|
||||
|
||||
|
||||
given(environment.getActiveProfiles()).willReturn(new String[]{"dev"});
|
||||
given(environment.getProperty("app.rate-limit.per-minute", "100")).willReturn("100");
|
||||
given(redisTemplate.opsForValue()).willReturn(valueOperations);
|
||||
@@ -250,4 +250,45 @@ class RateLimitInterceptorTest {
|
||||
// Then
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("应识别production配置文件为生产模式")
|
||||
void shouldRecognizeProductionProfile() {
|
||||
// Given
|
||||
Environment environment = mock(Environment.class);
|
||||
StringRedisTemplate redisTemplate = mock(StringRedisTemplate.class);
|
||||
|
||||
given(environment.getActiveProfiles()).willReturn(new String[]{"production"});
|
||||
given(environment.getProperty("app.rate-limit.per-minute", "100")).willReturn("100");
|
||||
|
||||
// When & Then - 不应抛出异常
|
||||
RateLimitInterceptor interceptor = new RateLimitInterceptor(environment, redisTemplate);
|
||||
assertThat(interceptor).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Redis返回null时应使用默认值1")
|
||||
void shouldUseDefaultValue_whenRedisReturnsNull() {
|
||||
// Given
|
||||
Environment environment = mock(Environment.class);
|
||||
StringRedisTemplate redisTemplate = mock(StringRedisTemplate.class);
|
||||
ValueOperations<String, String> valueOperations = mock(ValueOperations.class);
|
||||
|
||||
given(environment.getActiveProfiles()).willReturn(new String[]{"dev"});
|
||||
given(environment.getProperty("app.rate-limit.per-minute", "100")).willReturn("100");
|
||||
given(redisTemplate.opsForValue()).willReturn(valueOperations);
|
||||
given(valueOperations.increment(anyString())).willReturn(null); // Redis返回null
|
||||
|
||||
RateLimitInterceptor interceptor = new RateLimitInterceptor(environment, redisTemplate);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("X-API-Key", API_KEY);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
// When
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
// Then
|
||||
assertThat(result).isTrue();
|
||||
assertThat(response.getHeader("X-RateLimit-Remaining")).isEqualTo("99");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mosquito.project.web;
|
||||
|
||||
import com.mosquito.project.config.AppConfig;
|
||||
import com.mosquito.project.security.IntrospectionResponse;
|
||||
import com.mosquito.project.security.UserIntrospectionService;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -12,6 +13,9 @@ import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class UserAuthInterceptorTest {
|
||||
|
||||
@@ -28,4 +32,39 @@ class UserAuthInterceptorTest {
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("空白Authorization应拒绝")
|
||||
void shouldRejectRequest_whenBlankAuthorization() {
|
||||
UserIntrospectionService service = new UserIntrospectionService(new RestTemplateBuilder(), new AppConfig(), Optional.empty());
|
||||
UserAuthInterceptor interceptor = new UserAuthInterceptor(service);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Authorization", " "); // 空白
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("不活跃的token应拒绝")
|
||||
void shouldRejectRequest_whenTokenIsInactive() {
|
||||
// Given
|
||||
UserIntrospectionService service = mock(UserIntrospectionService.class);
|
||||
when(service.introspect(anyString())).thenReturn(IntrospectionResponse.inactive());
|
||||
|
||||
UserAuthInterceptor interceptor = new UserAuthInterceptor(service);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Authorization", "Bearer expired-token");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
// When
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
// Then
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user