|
| 1 | +package spring.memewikibe.infrastructure.ai; |
| 2 | + |
| 3 | +import org.junit.jupiter.api.BeforeEach; |
| 4 | +import org.junit.jupiter.api.DisplayName; |
| 5 | +import org.junit.jupiter.api.Test; |
| 6 | +import org.junit.jupiter.api.extension.ExtendWith; |
| 7 | +import org.mockito.Mock; |
| 8 | +import org.mockito.junit.jupiter.MockitoExtension; |
| 9 | +import spring.memewikibe.annotation.UnitTest; |
| 10 | + |
| 11 | +import static org.assertj.core.api.Assertions.assertThat; |
| 12 | +import static org.mockito.Mockito.verify; |
| 13 | +import static org.mockito.Mockito.when; |
| 14 | + |
| 15 | +@UnitTest |
| 16 | +@ExtendWith(MockitoExtension.class) |
| 17 | +@DisplayName("SimpleKoreanEmbeddingService 단위 테스트") |
| 18 | +class SimpleKoreanEmbeddingServiceTest { |
| 19 | + |
| 20 | + @Mock |
| 21 | + private EmbeddingService mockEmbeddingService; |
| 22 | + |
| 23 | + private SimpleKoreanEmbeddingService sut; |
| 24 | + |
| 25 | + @BeforeEach |
| 26 | + void setUp() { |
| 27 | + sut = new SimpleKoreanEmbeddingService(mockEmbeddingService); |
| 28 | + } |
| 29 | + |
| 30 | + @Test |
| 31 | + @DisplayName("embed: 정상적인 한글 텍스트를 임베딩 벡터로 변환") |
| 32 | + void embed_succeeds_withValidKoreanText() { |
| 33 | + // given |
| 34 | + String koreanText = "안녕하세요 밈 위키입니다"; |
| 35 | + float[] expectedEmbedding = new float[]{0.1f, 0.2f, 0.3f}; |
| 36 | + when(mockEmbeddingService.embed(koreanText)).thenReturn(expectedEmbedding); |
| 37 | + |
| 38 | + // when |
| 39 | + float[] result = sut.embed(koreanText); |
| 40 | + |
| 41 | + // then |
| 42 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 43 | + verify(mockEmbeddingService).embed(koreanText); |
| 44 | + } |
| 45 | + |
| 46 | + @Test |
| 47 | + @DisplayName("embed: null 텍스트를 delegate에 전달") |
| 48 | + void embed_delegatesNullText_toUnderlyingService() { |
| 49 | + // given |
| 50 | + String nullText = null; |
| 51 | + float[] expectedEmbedding = new float[]{0.0f, 0.0f, 0.0f}; |
| 52 | + when(mockEmbeddingService.embed(nullText)).thenReturn(expectedEmbedding); |
| 53 | + |
| 54 | + // when |
| 55 | + float[] result = sut.embed(nullText); |
| 56 | + |
| 57 | + // then |
| 58 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 59 | + verify(mockEmbeddingService).embed(nullText); |
| 60 | + } |
| 61 | + |
| 62 | + @Test |
| 63 | + @DisplayName("embed: 빈 문자열을 delegate에 전달") |
| 64 | + void embed_delegatesEmptyString_toUnderlyingService() { |
| 65 | + // given |
| 66 | + String emptyText = ""; |
| 67 | + float[] expectedEmbedding = new float[]{0.0f, 0.0f, 0.0f}; |
| 68 | + when(mockEmbeddingService.embed(emptyText)).thenReturn(expectedEmbedding); |
| 69 | + |
| 70 | + // when |
| 71 | + float[] result = sut.embed(emptyText); |
| 72 | + |
| 73 | + // then |
| 74 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 75 | + verify(mockEmbeddingService).embed(emptyText); |
| 76 | + } |
| 77 | + |
| 78 | + @Test |
| 79 | + @DisplayName("embed: 공백만 있는 문자열을 delegate에 전달") |
| 80 | + void embed_delegatesBlankString_toUnderlyingService() { |
| 81 | + // given |
| 82 | + String blankText = " "; |
| 83 | + float[] expectedEmbedding = new float[]{0.0f, 0.0f, 0.0f}; |
| 84 | + when(mockEmbeddingService.embed(blankText)).thenReturn(expectedEmbedding); |
| 85 | + |
| 86 | + // when |
| 87 | + float[] result = sut.embed(blankText); |
| 88 | + |
| 89 | + // then |
| 90 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 91 | + verify(mockEmbeddingService).embed(blankText); |
| 92 | + } |
| 93 | + |
| 94 | + @Test |
| 95 | + @DisplayName("embed: 긴 한글 텍스트를 임베딩 벡터로 변환") |
| 96 | + void embed_succeeds_withLongKoreanText() { |
| 97 | + // given |
| 98 | + String longText = "밈(Meme)은 문화적 정보나 아이디어가 사람들 사이에서 전파되는 것을 설명하는 개념입니다. " + |
| 99 | + "인터넷 밈은 일반적으로 이미지, 동영상, 해시태그 등의 형태로 소셜 미디어를 통해 빠르게 확산됩니다."; |
| 100 | + float[] expectedEmbedding = new float[1536]; // typical embedding dimension |
| 101 | + when(mockEmbeddingService.embed(longText)).thenReturn(expectedEmbedding); |
| 102 | + |
| 103 | + // when |
| 104 | + float[] result = sut.embed(longText); |
| 105 | + |
| 106 | + // then |
| 107 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 108 | + assertThat(result.length).isEqualTo(1536); |
| 109 | + verify(mockEmbeddingService).embed(longText); |
| 110 | + } |
| 111 | + |
| 112 | + @Test |
| 113 | + @DisplayName("embed: 혼합된 한글/영어 텍스트를 처리") |
| 114 | + void embed_succeeds_withMixedKoreanEnglishText() { |
| 115 | + // given |
| 116 | + String mixedText = "Meme은 밈입니다 #trending #인기밈"; |
| 117 | + float[] expectedEmbedding = new float[]{0.5f, 0.6f, 0.7f}; |
| 118 | + when(mockEmbeddingService.embed(mixedText)).thenReturn(expectedEmbedding); |
| 119 | + |
| 120 | + // when |
| 121 | + float[] result = sut.embed(mixedText); |
| 122 | + |
| 123 | + // then |
| 124 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 125 | + verify(mockEmbeddingService).embed(mixedText); |
| 126 | + } |
| 127 | + |
| 128 | + @Test |
| 129 | + @DisplayName("embed: 특수문자가 포함된 텍스트를 처리") |
| 130 | + void embed_succeeds_withSpecialCharacters() { |
| 131 | + // given |
| 132 | + String textWithSpecialChars = "안녕하세요! 😀 #밈 @사용자 https://example.com"; |
| 133 | + float[] expectedEmbedding = new float[]{0.8f, 0.9f, 1.0f}; |
| 134 | + when(mockEmbeddingService.embed(textWithSpecialChars)).thenReturn(expectedEmbedding); |
| 135 | + |
| 136 | + // when |
| 137 | + float[] result = sut.embed(textWithSpecialChars); |
| 138 | + |
| 139 | + // then |
| 140 | + assertThat(result).isEqualTo(expectedEmbedding); |
| 141 | + verify(mockEmbeddingService).embed(textWithSpecialChars); |
| 142 | + } |
| 143 | +} |
0 commit comments