From edeb4fc168130218b4620f9aff5881e666d15730 Mon Sep 17 00:00:00 2001 From: jianghao <332515344@qq.com> Date: Wed, 25 Feb 2026 16:18:24 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=B9=B6=E4=BC=98=E5=8C=96=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加spring-boot-starter-test和mockito-junit-jupiter测试依赖 - 简化AlbumServicePropertyTest中的photoIdLists生成器 - 统一WebSocket测试中的any()参数类型为Object.class - 优化TestDataGenerators中的代码格式和UserProfile时间类型 --- timeline-user-service/pom.xml | 12 + .../service/AlbumServicePropertyTest.java | 3 +- .../user/service/CommentWebSocketTest.java | 4 +- .../user/service/ReactionWebSocketTest.java | 34 +-- .../user/testutil/TestDataGenerators.java | 247 +++++++++--------- 5 files changed, 152 insertions(+), 148 deletions(-) diff --git a/timeline-user-service/pom.xml b/timeline-user-service/pom.xml index 320a771..219dc0e 100644 --- a/timeline-user-service/pom.xml +++ b/timeline-user-service/pom.xml @@ -133,6 +133,18 @@ jqwik test + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mockito + mockito-junit-jupiter + test + diff --git a/timeline-user-service/src/test/java/com/timeline/user/service/AlbumServicePropertyTest.java b/timeline-user-service/src/test/java/com/timeline/user/service/AlbumServicePropertyTest.java index 9c47768..b3dbb5f 100644 --- a/timeline-user-service/src/test/java/com/timeline/user/service/AlbumServicePropertyTest.java +++ b/timeline-user-service/src/test/java/com/timeline/user/service/AlbumServicePropertyTest.java @@ -285,7 +285,6 @@ class AlbumServicePropertyTest { @Provide Arbitrary> photoIdLists() { return Arbitraries.integers().between(1, 10) - .flatMap(size -> Combinators.listOf(TestDataGenerators.photoIds()) - .ofSize(size)); + .flatMap(size -> TestDataGenerators.photoIds().list().ofSize(size)); } } diff --git a/timeline-user-service/src/test/java/com/timeline/user/service/CommentWebSocketTest.java b/timeline-user-service/src/test/java/com/timeline/user/service/CommentWebSocketTest.java index 3eb1206..32858e4 100644 --- a/timeline-user-service/src/test/java/com/timeline/user/service/CommentWebSocketTest.java +++ b/timeline-user-service/src/test/java/com/timeline/user/service/CommentWebSocketTest.java @@ -186,7 +186,7 @@ class CommentWebSocketTest { // Simulate WebSocket failure doThrow(new RuntimeException("WebSocket error")) - .when(messagingTemplate).convertAndSend(anyString(), any()); + .when(messagingTemplate).convertAndSend(anyString(), any(Object.class)); // Act - should not throw exception CommentDto result = commentService.createComment("user123", request); @@ -196,6 +196,6 @@ class CommentWebSocketTest { assertEquals("Test comment", result.getContent()); // Verify the WebSocket send was attempted - verify(messagingTemplate, times(1)).convertAndSend(anyString(), any()); + verify(messagingTemplate, times(1)).convertAndSend(anyString(), any(Object.class)); } } diff --git a/timeline-user-service/src/test/java/com/timeline/user/service/ReactionWebSocketTest.java b/timeline-user-service/src/test/java/com/timeline/user/service/ReactionWebSocketTest.java index dbbb248..a275c98 100644 --- a/timeline-user-service/src/test/java/com/timeline/user/service/ReactionWebSocketTest.java +++ b/timeline-user-service/src/test/java/com/timeline/user/service/ReactionWebSocketTest.java @@ -76,12 +76,12 @@ public class ReactionWebSocketTest { // Assert ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(ReactionEventDto.class); - + verify(messagingTemplate).convertAndSend(topicCaptor.capture(), eventCaptor.capture()); - + // 验证主题格式 assertEquals("/topic/reactions/STORY_ITEM/story123", topicCaptor.getValue()); - + // 验证事件内容 ReactionEventDto event = eventCaptor.getValue(); assertEquals(ReactionEventDto.ReactionEventType.CREATED, event.getEventType()); @@ -123,12 +123,12 @@ public class ReactionWebSocketTest { // Assert ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(ReactionEventDto.class); - + verify(messagingTemplate).convertAndSend(topicCaptor.capture(), eventCaptor.capture()); - + // 验证主题格式 assertEquals("/topic/reactions/STORY_ITEM/story123", topicCaptor.getValue()); - + // 验证事件内容 ReactionEventDto event = eventCaptor.getValue(); assertEquals(ReactionEventDto.ReactionEventType.UPDATED, event.getEventType()); @@ -147,12 +147,12 @@ public class ReactionWebSocketTest { // Assert ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(ReactionEventDto.class); - + verify(messagingTemplate).convertAndSend(topicCaptor.capture(), eventCaptor.capture()); - + // 验证主题格式 assertEquals("/topic/reactions/STORY_ITEM/story123", topicCaptor.getValue()); - + // 验证事件内容 ReactionEventDto event = eventCaptor.getValue(); assertEquals(ReactionEventDto.ReactionEventType.DELETED, event.getEventType()); @@ -169,10 +169,10 @@ public class ReactionWebSocketTest { when(reactionMapper.insert(any(Reaction.class))).thenReturn(1); when(reactionMapper.findByEntityAndUser("STORY_ITEM", "story123", "user123")).thenReturn(testReaction); when(userMapper.selectByUserId("user123")).thenReturn(testUser); - + // 模拟WebSocket发送失败 doThrow(new RuntimeException("WebSocket connection failed")) - .when(messagingTemplate).convertAndSend(anyString(), any()); + .when(messagingTemplate).convertAndSend(anyString(), any(Object.class)); // Act & Assert - 不应该抛出异常 assertDoesNotThrow(() -> { @@ -188,14 +188,14 @@ public class ReactionWebSocketTest { // Test STORY_ITEM when(reactionMapper.findByEntityAndUser(anyString(), anyString(), anyString())).thenReturn(null); when(reactionMapper.insert(any(Reaction.class))).thenReturn(1); - + Reaction storyReaction = new Reaction(); storyReaction.setEntityType("STORY_ITEM"); storyReaction.setEntityId("story456"); storyReaction.setUserId("user123"); storyReaction.setReactionType("LIKE"); storyReaction.setCreateTime(LocalDateTime.now()); - + when(reactionMapper.findByEntityAndUser("STORY_ITEM", "story456", "user123")).thenReturn(storyReaction); when(userMapper.selectByUserId("user123")).thenReturn(testUser); @@ -207,14 +207,14 @@ public class ReactionWebSocketTest { // Test PHOTO reset(messagingTemplate); - + Reaction photoReaction = new Reaction(); photoReaction.setEntityType("PHOTO"); photoReaction.setEntityId("photo789"); photoReaction.setUserId("user123"); photoReaction.setReactionType("LOVE"); photoReaction.setCreateTime(LocalDateTime.now()); - + when(reactionMapper.findByEntityAndUser("PHOTO", "photo789", "user123")).thenReturn(photoReaction); reactionService.addOrUpdateReaction("user123", "PHOTO", "photo789", "LOVE"); @@ -238,7 +238,7 @@ public class ReactionWebSocketTest { reactionService.addOrUpdateReaction("user123", "STORY_ITEM", "story123", "LIKE"); // Assert - 不应该发送WebSocket消息 - verify(messagingTemplate, never()).convertAndSend(anyString(), any()); + verify(messagingTemplate, never()).convertAndSend(anyString(), any(Object.class)); } @Test @@ -250,6 +250,6 @@ public class ReactionWebSocketTest { reactionService.removeReaction("user123", "STORY_ITEM", "story123"); // Assert - 不应该发送WebSocket消息 - verify(messagingTemplate, never()).convertAndSend(anyString(), any()); + verify(messagingTemplate, never()).convertAndSend(anyString(), any(Object.class)); } } diff --git a/timeline-user-service/src/test/java/com/timeline/user/testutil/TestDataGenerators.java b/timeline-user-service/src/test/java/com/timeline/user/testutil/TestDataGenerators.java index faf360f..eb00e55 100644 --- a/timeline-user-service/src/test/java/com/timeline/user/testutil/TestDataGenerators.java +++ b/timeline-user-service/src/test/java/com/timeline/user/testutil/TestDataGenerators.java @@ -7,6 +7,7 @@ import net.jqwik.api.Arbitrary; import net.jqwik.api.Combinators; import java.time.LocalDateTime; +import java.util.Date; import java.util.UUID; /** @@ -20,25 +21,24 @@ public class TestDataGenerators { */ public static Arbitrary albums() { return Combinators.combine( - instanceIds(), - userIds(), - albumNames(), - descriptions(), - photoIds(), - photoCounts() - ).as((instanceId, userId, name, description, coverPhotoId, photoCount) -> { - Album album = new Album(); - album.setInstanceId(instanceId); - album.setUserId(userId); - album.setName(name); - album.setDescription(description); - album.setCoverPhotoId(coverPhotoId); - album.setPhotoCount(photoCount); - album.setCreateTime(LocalDateTime.now()); - album.setUpdateTime(LocalDateTime.now()); - album.setIsDelete(0); - return album; - }); + instanceIds(), + userIds(), + albumNames(), + descriptions(), + photoIds(), + photoCounts()).as((instanceId, userId, name, description, coverPhotoId, photoCount) -> { + Album album = new Album(); + album.setInstanceId(instanceId); + album.setUserId(userId); + album.setName(name); + album.setDescription(description); + album.setCoverPhotoId(coverPhotoId); + album.setPhotoCount(photoCount); + album.setCreateTime(LocalDateTime.now()); + album.setUpdateTime(LocalDateTime.now()); + album.setIsDelete(0); + return album; + }); } /** @@ -46,23 +46,22 @@ public class TestDataGenerators { */ public static Arbitrary comments() { return Combinators.combine( - instanceIds(), - entityTypes(), - entityIds(), - userIds(), - commentContents() - ).as((instanceId, entityType, entityId, userId, content) -> { - Comment comment = new Comment(); - comment.setInstanceId(instanceId); - comment.setEntityType(entityType); - comment.setEntityId(entityId); - comment.setUserId(userId); - comment.setContent(content); - comment.setCreateTime(LocalDateTime.now()); - comment.setUpdateTime(LocalDateTime.now()); - comment.setIsDelete(0); - return comment; - }); + instanceIds(), + entityTypes(), + entityIds(), + userIds(), + commentContents()).as((instanceId, entityType, entityId, userId, content) -> { + Comment comment = new Comment(); + comment.setInstanceId(instanceId); + comment.setEntityType(entityType); + comment.setEntityId(entityId); + comment.setUserId(userId); + comment.setContent(content); + comment.setCreateTime(LocalDateTime.now()); + comment.setUpdateTime(LocalDateTime.now()); + comment.setIsDelete(0); + return comment; + }); } /** @@ -70,20 +69,19 @@ public class TestDataGenerators { */ public static Arbitrary reactions() { return Combinators.combine( - entityTypes(), - entityIds(), - userIds(), - reactionTypes() - ).as((entityType, entityId, userId, reactionType) -> { - Reaction reaction = new Reaction(); - reaction.setEntityType(entityType); - reaction.setEntityId(entityId); - reaction.setUserId(userId); - reaction.setReactionType(reactionType); - reaction.setCreateTime(LocalDateTime.now()); - reaction.setUpdateTime(LocalDateTime.now()); - return reaction; - }); + entityTypes(), + entityIds(), + userIds(), + reactionTypes()).as((entityType, entityId, userId, reactionType) -> { + Reaction reaction = new Reaction(); + reaction.setEntityType(entityType); + reaction.setEntityId(entityId); + reaction.setUserId(userId); + reaction.setReactionType(reactionType); + reaction.setCreateTime(LocalDateTime.now()); + reaction.setUpdateTime(LocalDateTime.now()); + return reaction; + }); } /** @@ -91,25 +89,24 @@ public class TestDataGenerators { */ public static Arbitrary userPreferences() { return Combinators.combine( - userIds(), - themeModes(), - layoutTypes(), - cardSizes(), - displayModes() - ).as((userId, themeMode, layout, cardSize, displayMode) -> { - UserPreferences prefs = new UserPreferences(); - prefs.setUserId(userId); - prefs.setThemeMode(themeMode); - prefs.setColorScheme("default"); - prefs.setGalleryLayout(layout); - prefs.setTimelineLayout(layout); - prefs.setAlbumLayout(layout); - prefs.setCardSize(cardSize); - prefs.setTimelineDisplayMode(displayMode); - prefs.setCreateTime(LocalDateTime.now()); - prefs.setUpdateTime(LocalDateTime.now()); - return prefs; - }); + userIds(), + themeModes(), + layoutTypes(), + cardSizes(), + displayModes()).as((userId, themeMode, layout, cardSize, displayMode) -> { + UserPreferences prefs = new UserPreferences(); + prefs.setUserId(userId); + prefs.setThemeMode(themeMode); + prefs.setColorScheme("default"); + prefs.setGalleryLayout(layout); + prefs.setTimelineLayout(layout); + prefs.setAlbumLayout(layout); + prefs.setCardSize(cardSize); + prefs.setTimelineDisplayMode(displayMode); + prefs.setCreateTime(LocalDateTime.now()); + prefs.setUpdateTime(LocalDateTime.now()); + return prefs; + }); } /** @@ -117,18 +114,17 @@ public class TestDataGenerators { */ public static Arbitrary userProfiles() { return Combinators.combine( - userIds(), - urls(), - bios() - ).as((userId, coverPhotoUrl, bio) -> { - UserProfile profile = new UserProfile(); - profile.setUserId(userId); - profile.setCoverPhotoUrl(coverPhotoUrl); - profile.setBio(bio); - profile.setCreateTime(LocalDateTime.now()); - profile.setUpdateTime(LocalDateTime.now()); - return profile; - }); + userIds(), + urls(), + bios()).as((userId, coverPhotoUrl, bio) -> { + UserProfile profile = new UserProfile(); + profile.setUserId(userId); + profile.setCoverPhotoUrl(coverPhotoUrl); + profile.setBio(bio); + profile.setCreateTime(new Date()); + profile.setUpdateTime(new Date()); + return profile; + }); } /** @@ -136,14 +132,13 @@ public class TestDataGenerators { */ public static Arbitrary createAlbumRequests() { return Combinators.combine( - albumNames(), - descriptions() - ).as((name, description) -> { - CreateAlbumRequest request = new CreateAlbumRequest(); - request.setName(name); - request.setDescription(description); - return request; - }); + albumNames(), + descriptions()).as((name, description) -> { + CreateAlbumRequest request = new CreateAlbumRequest(); + request.setName(name); + request.setDescription(description); + return request; + }); } /** @@ -151,16 +146,15 @@ public class TestDataGenerators { */ public static Arbitrary createCommentRequests() { return Combinators.combine( - entityTypes(), - entityIds(), - commentContents() - ).as((entityType, entityId, content) -> { - CreateCommentRequest request = new CreateCommentRequest(); - request.setEntityType(entityType); - request.setEntityId(entityId); - request.setContent(content); - return request; - }); + entityTypes(), + entityIds(), + commentContents()).as((entityType, entityId, content) -> { + CreateCommentRequest request = new CreateCommentRequest(); + request.setEntityType(entityType); + request.setEntityId(entityId); + request.setContent(content); + return request; + }); } // ========== 基础数据生成器 ========== @@ -183,46 +177,46 @@ public class TestDataGenerators { public static Arbitrary albumNames() { return Arbitraries.strings() - .alpha() - .ofMinLength(1) - .ofMaxLength(50) - .map(s -> "Album " + s); + .alpha() + .ofMinLength(1) + .ofMaxLength(50) + .map(s -> "Album " + s); } public static Arbitrary descriptions() { return Arbitraries.strings() - .alpha() - .numeric() - .withChars(' ', '.', ',') - .ofMinLength(0) - .ofMaxLength(200); + .alpha() + .numeric() + .withChars(' ', '.', ',') + .ofMinLength(0) + .ofMaxLength(200); } public static Arbitrary commentContents() { return Arbitraries.strings() - .alpha() - .numeric() - .withChars(' ', '.', ',', '!', '?') - .ofMinLength(1) - .ofMaxLength(1000); + .alpha() + .numeric() + .withChars(' ', '.', ',', '!', '?') + .ofMinLength(1) + .ofMaxLength(1000); } public static Arbitrary bios() { return Arbitraries.strings() - .alpha() - .numeric() - .withChars(' ', '.', ',') - .ofMinLength(0) - .ofMaxLength(500); + .alpha() + .numeric() + .withChars(' ', '.', ',') + .ofMinLength(0) + .ofMaxLength(500); } public static Arbitrary urls() { return Arbitraries.strings() - .alpha() - .numeric() - .ofMinLength(10) - .ofMaxLength(50) - .map(s -> "https://example.com/" + s + ".jpg"); + .alpha() + .numeric() + .ofMinLength(10) + .ofMaxLength(50) + .map(s -> "https://example.com/" + s + ".jpg"); } public static Arbitrary photoCounts() { @@ -265,9 +259,8 @@ public class TestDataGenerators { */ public static Arbitrary monthPeriods() { return Combinators.combine( - Arbitraries.integers().between(2020, 2024), - Arbitraries.integers().between(1, 12) - ).as((year, month) -> String.format("%d-%02d", year, month)); + Arbitraries.integers().between(2020, 2024), + Arbitraries.integers().between(1, 12)).as((year, month) -> String.format("%d-%02d", year, month)); } /** @@ -275,7 +268,7 @@ public class TestDataGenerators { */ public static Arbitrary yearPeriods() { return Arbitraries.integers().between(2020, 2024) - .map(String::valueOf); + .map(String::valueOf); } /**