test(cache): 修复CacheConfigTest边界值测试
- 修改 shouldVerifyCacheManager_withMaximumIntegerTtl 为 shouldVerifyCacheManager_withMaximumAllowedTtl - 使用正确的最大TTL值(10080分钟,7天)而不是 Integer.MAX_VALUE - 新增 shouldThrowException_whenTtlExceedsMaximum 测试验证边界检查 - 所有1266个测试用例通过 - 覆盖率: 指令81.89%, 行88.48%, 分支51.55% docs: 添加项目状态报告 - 生成 PROJECT_STATUS_REPORT.md 详细记录项目当前状态 - 包含质量指标、已完成功能、待办事项和技术债务
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
package com.mosquito.project.service;
|
||||
|
||||
import com.mosquito.project.persistence.entity.ShortLinkEntity;
|
||||
import com.mosquito.project.persistence.repository.ShortLinkRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@DisplayName("短链服务测试")
|
||||
class ShortLinkServiceTest {
|
||||
|
||||
@Mock
|
||||
private ShortLinkRepository repository;
|
||||
|
||||
@InjectMocks
|
||||
private ShortLinkService shortLinkService;
|
||||
|
||||
private final String TEST_URL = "https://example.com/test";
|
||||
private final String TEST_CODE = "test123";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
lenient().when(repository.existsByCode(anyString())).thenReturn(false);
|
||||
lenient().when(repository.save(any(ShortLinkEntity.class))).thenAnswer(invocation -> {
|
||||
ShortLinkEntity entity = invocation.getArgument(0);
|
||||
entity.setId(1L);
|
||||
entity.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
|
||||
return entity;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 基本功能")
|
||||
void shouldCreateShortLink_Basic() {
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(TEST_URL);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(TEST_URL, result.getOriginalUrl());
|
||||
assertNotNull(result.getCode());
|
||||
assertEquals(8, result.getCode().length()); // DEFAULT_CODE_LEN
|
||||
assertNotNull(result.getCreatedAt());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 带activityId参数")
|
||||
void shouldCreateShortLink_WithActivityId() {
|
||||
String urlWithActivity = TEST_URL + "?activityId=123";
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(urlWithActivity);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(urlWithActivity, result.getOriginalUrl());
|
||||
assertEquals(123L, result.getActivityId());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 带inviter参数")
|
||||
void shouldCreateShortLink_WithInviter() {
|
||||
String urlWithInviter = TEST_URL + "?inviter=456";
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(urlWithInviter);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(urlWithInviter, result.getOriginalUrl());
|
||||
assertEquals(456L, result.getInviterUserId());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 带多个参数")
|
||||
void shouldCreateShortLink_WithMultipleParams() {
|
||||
String urlWithParams = TEST_URL + "?activityId=123&inviter=456&other=value";
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(urlWithParams);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(urlWithParams, result.getOriginalUrl());
|
||||
assertEquals(123L, result.getActivityId());
|
||||
assertEquals(456L, result.getInviterUserId());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 代码冲突时重新生成")
|
||||
void shouldCreateShortLink_WhenCodeConflict() {
|
||||
// Given - 第一次生成冲突,第二次成功
|
||||
when(repository.existsByCode(anyString()))
|
||||
.thenReturn(true) // 第一次冲突
|
||||
.thenReturn(false); // 第二次成功
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(TEST_URL);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(result.getCode());
|
||||
verify(repository, times(2)).existsByCode(anyString());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 多次冲突时增加长度")
|
||||
void shouldCreateShortLink_WithIncreasedLength() {
|
||||
// Given - 所有尝试都冲突
|
||||
when(repository.existsByCode(anyString())).thenReturn(true);
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(TEST_URL);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(result.getCode());
|
||||
assertEquals(10, result.getCode().length()); // len + 2
|
||||
verify(repository, times(5)).existsByCode(anyString()); // 5次重试
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("创建短链 - 无效URL不影响核心功能")
|
||||
void shouldCreateShortLink_WithInvalidUrl() {
|
||||
String invalidUrl = "not-a-valid-url";
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(invalidUrl);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(invalidUrl, result.getOriginalUrl());
|
||||
assertNotNull(result.getCode());
|
||||
assertNull(result.getActivityId());
|
||||
assertNull(result.getInviterUserId());
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("根据代码查找短链 - 找到")
|
||||
void shouldFindByCode_WhenExists() {
|
||||
// Given
|
||||
ShortLinkEntity entity = new ShortLinkEntity();
|
||||
entity.setCode(TEST_CODE);
|
||||
entity.setOriginalUrl(TEST_URL);
|
||||
when(repository.findByCode(TEST_CODE)).thenReturn(Optional.of(entity));
|
||||
|
||||
// When
|
||||
Optional<ShortLinkEntity> result = shortLinkService.findByCode(TEST_CODE);
|
||||
|
||||
// Then
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(TEST_CODE, result.get().getCode());
|
||||
assertEquals(TEST_URL, result.get().getOriginalUrl());
|
||||
verify(repository).findByCode(TEST_CODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("根据代码查找短链 - 未找到")
|
||||
void shouldReturnEmpty_WhenNotExists() {
|
||||
// Given
|
||||
when(repository.findByCode(TEST_CODE)).thenReturn(Optional.empty());
|
||||
|
||||
// When
|
||||
Optional<ShortLinkEntity> result = shortLinkService.findByCode(TEST_CODE);
|
||||
|
||||
// Then
|
||||
assertFalse(result.isPresent());
|
||||
verify(repository).findByCode(TEST_CODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("URL参数解析 - 编码的参数")
|
||||
void shouldParseEncodedParams() {
|
||||
String urlWithEncoded = TEST_URL + "?activityId=" + java.net.URLEncoder.encode("123", java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(urlWithEncoded);
|
||||
|
||||
// Then
|
||||
assertEquals(123L, result.getActivityId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("URL参数解析 - 格式错误的参数")
|
||||
void shouldHandleMalformedParams() {
|
||||
String urlWithMalformed = TEST_URL + "?activityId=abc&inviter=xyz";
|
||||
|
||||
// When
|
||||
ShortLinkEntity result = shortLinkService.create(urlWithMalformed);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
// 应该忽略格式错误的参数,但不影响创建
|
||||
verify(repository).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("生成代码的唯一性验证")
|
||||
void shouldGenerateUniqueCodes() {
|
||||
// When
|
||||
ShortLinkEntity result1 = shortLinkService.create(TEST_URL + "1");
|
||||
ShortLinkEntity result2 = shortLinkService.create(TEST_URL + "2");
|
||||
|
||||
// Then
|
||||
assertNotEquals(result1.getCode(), result2.getCode());
|
||||
verify(repository, times(2)).save(any(ShortLinkEntity.class));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user