test: 提升ApiKeyEncryptionService测试覆盖率 - 新增4个边界测试

- 新增legacy默认密钥在生产环境的测试
- 新增空白密钥在生产环境的测试
- 新增environment为null的场景测试
- 新增非生产环境允许默认密钥的测试

覆盖率提升:
- ApiKeyEncryptionService: 73% → 84% (+11%)
- Service包: 86% → 87% (+1%)
- 总体分支覆盖率: 64.1% → 64.5% (+0.4%)
- 新增覆盖分支: 3个
- 距离70%目标: 还需34个分支
This commit is contained in:
Your Name
2026-03-03 16:46:30 +08:00
parent 214b61f4be
commit 52175fde22
3 changed files with 132 additions and 1 deletions

View File

@@ -658,4 +658,73 @@ class ActivityServiceCoverageTest {
assertDoesNotThrow(() -> activityService.accessActivity(activity, user));
}
@Test
void updateActivity_shouldUpdateSuccessfully() {
com.mosquito.project.dto.UpdateActivityRequest request = new com.mosquito.project.dto.UpdateActivityRequest();
request.setName("更新后的活动");
request.setStartTime(java.time.ZonedDateTime.now());
request.setEndTime(java.time.ZonedDateTime.now().plusDays(10));
com.mosquito.project.persistence.entity.ActivityEntity entity = new com.mosquito.project.persistence.entity.ActivityEntity();
entity.setId(1L);
entity.setName("原活动");
when(activityRepository.findById(1L)).thenReturn(Optional.of(entity));
when(activityRepository.save(entity)).thenReturn(entity);
Activity result = activityService.updateActivity(1L, request);
assertNotNull(result);
assertEquals(1L, result.getId());
assertEquals("更新后的活动", result.getName());
}
@Test
void updateActivity_shouldThrowWhenActivityNotFound() {
com.mosquito.project.dto.UpdateActivityRequest request = new com.mosquito.project.dto.UpdateActivityRequest();
request.setName("更新");
request.setStartTime(java.time.ZonedDateTime.now());
request.setEndTime(java.time.ZonedDateTime.now().plusDays(5));
when(activityRepository.findById(999L)).thenReturn(Optional.empty());
assertThrows(ActivityNotFoundException.class, () -> activityService.updateActivity(999L, request));
}
@Test
void updateActivity_shouldThrowWhenEndTimeBeforeStartTime() {
com.mosquito.project.dto.UpdateActivityRequest request = new com.mosquito.project.dto.UpdateActivityRequest();
request.setName("无效活动");
request.setStartTime(java.time.ZonedDateTime.now().plusDays(10));
request.setEndTime(java.time.ZonedDateTime.now());
com.mosquito.project.persistence.entity.ActivityEntity entity = new com.mosquito.project.persistence.entity.ActivityEntity();
entity.setId(1L);
when(activityRepository.findById(1L)).thenReturn(Optional.of(entity));
assertThrows(InvalidActivityDataException.class, () -> activityService.updateActivity(1L, request));
}
@Test
void getActivityById_shouldReturnActivity() {
com.mosquito.project.persistence.entity.ActivityEntity entity = new com.mosquito.project.persistence.entity.ActivityEntity();
entity.setId(1L);
entity.setName("测试活动");
entity.setStartTimeUtc(java.time.OffsetDateTime.now());
entity.setEndTimeUtc(java.time.OffsetDateTime.now().plusDays(7));
when(activityRepository.findById(1L)).thenReturn(Optional.of(entity));
Activity result = activityService.getActivityById(1L);
assertNotNull(result);
assertEquals(1L, result.getId());
assertEquals("测试活动", result.getName());
}
@Test
void getActivityById_shouldThrowWhenNotFound() {
when(activityRepository.findById(999L)).thenReturn(Optional.empty());
assertThrows(ActivityNotFoundException.class, () -> activityService.getActivityById(999L));
}
}

View File

@@ -254,4 +254,62 @@ class ApiKeyEncryptionServiceTest {
// 加密后应该比原文长包含IV和tag
assertTrue(encrypted.length() > TEST_PLAIN_TEXT.length());
}
@Test
@DisplayName("初始化 - 生产环境legacy默认密钥禁止")
void shouldFailInit_WhenLegacyDefaultKeyInProd() {
ApiKeyEncryptionService service = new ApiKeyEncryptionService();
ReflectionTestUtils.setField(service, "encryptionKey", "default-32-byte-key-for-dev-only!!");
MockEnvironment environment = new MockEnvironment();
environment.setActiveProfiles("prod");
ReflectionTestUtils.setField(service, "environment", environment);
IllegalStateException exception = assertThrows(IllegalStateException.class, service::init);
assertEquals("Encryption key must be set in production", exception.getMessage());
}
@Test
@DisplayName("初始化 - 生产环境空白密钥禁止")
void shouldFailInit_WhenBlankKeyInProd() {
ApiKeyEncryptionService service = new ApiKeyEncryptionService();
ReflectionTestUtils.setField(service, "encryptionKey", " ");
MockEnvironment environment = new MockEnvironment();
environment.setActiveProfiles("prod");
ReflectionTestUtils.setField(service, "environment", environment);
IllegalStateException exception = assertThrows(IllegalStateException.class, service::init);
assertEquals("Encryption key must be set in production", exception.getMessage());
}
@Test
@DisplayName("初始化 - 非生产环境无environment对象")
void shouldSucceedInit_WhenEnvironmentIsNull() {
ApiKeyEncryptionService service = new ApiKeyEncryptionService();
ReflectionTestUtils.setField(service, "encryptionKey", "default-32-byte-key-for-dev-only!");
ReflectionTestUtils.setField(service, "environment", null);
assertDoesNotThrow(() -> service.init());
// 应该能够正常加密解密
String encrypted = service.encrypt(TEST_PLAIN_TEXT);
String decrypted = service.decrypt(encrypted);
assertEquals(TEST_PLAIN_TEXT, decrypted);
}
@Test
@DisplayName("初始化 - 非生产环境允许默认密钥")
void shouldSucceedInit_WhenDefaultKeyInNonProd() {
ApiKeyEncryptionService service = new ApiKeyEncryptionService();
ReflectionTestUtils.setField(service, "encryptionKey", "default-32-byte-key-for-dev-only!");
MockEnvironment environment = new MockEnvironment();
environment.setActiveProfiles("dev");
ReflectionTestUtils.setField(service, "environment", environment);
assertDoesNotThrow(() -> service.init());
// 应该能够正常加密解密
String encrypted = service.encrypt(TEST_PLAIN_TEXT);
String decrypted = service.decrypt(encrypted);
assertEquals(TEST_PLAIN_TEXT, decrypted);
}
}