Skip to content

Commit f436f4c

Browse files
committed
test: 변경된 캐싱 구조에 맞게 단위 테스트 수정
1 parent 4f70b27 commit f436f4c

File tree

1 file changed

+56
-173
lines changed

1 file changed

+56
-173
lines changed

src/test/java/com/example/log4u/domain/Map/service/MapServiceTest.java

Lines changed: 56 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.util.List;
99
import java.util.Optional;
1010
import java.util.Set;
11-
import java.util.stream.Collectors;
1211

1312
import org.junit.jupiter.api.DisplayName;
1413
import org.junit.jupiter.api.Test;
@@ -22,7 +21,7 @@
2221
import com.example.log4u.domain.diary.service.DiaryGeohashService;
2322
import com.example.log4u.domain.diary.service.DiaryService;
2423
import com.example.log4u.domain.map.cache.dao.ClusterCacheDao;
25-
import com.example.log4u.domain.map.cache.dao.DiaryCacheDao;
24+
import com.example.log4u.domain.map.cache.dao.MarkerCacheDao;
2625
import com.example.log4u.domain.map.dto.response.DiaryClusterResponseDto;
2726
import com.example.log4u.domain.map.dto.response.DiaryMarkerResponseDto;
2827
import com.example.log4u.domain.map.exception.InvalidGeohashException;
@@ -50,7 +49,7 @@ class MapServiceTest {
5049
private DiaryRepository diaryRepository;
5150

5251
@Mock
53-
private DiaryCacheDao diaryCacheDao;
52+
private MarkerCacheDao markerCacheDao;
5453

5554
@Mock
5655
private DiaryService diaryService;
@@ -61,222 +60,106 @@ class MapServiceTest {
6160
@Mock
6261
private ClusterCacheDao clusterCacheDao;
6362

64-
private static final String GEOHASH = "abc";
65-
private static final int VALID_LEVEL_1 = 1;
66-
private static final int VALID_LEVEL_2 = 2;
63+
private static final String GEOHASH_L3 = "abc";
64+
private static final String GEOHASH_L5 = "abcde";
6765

68-
private final List<DiaryClusterResponseDto> mockResult = List.of(
66+
private static final int LEVEL_SIDO = 1;
67+
private static final int LEVEL_SIGG = 2;
68+
69+
private final List<DiaryClusterResponseDto> clusters = List.of(
6970
new DiaryClusterResponseDto("서울", 1L, 37.5665, 126.9780, 10L)
7071
);
7172

73+
private final List<DiaryMarkerResponseDto> markers = List.of(
74+
DiaryMarkerResponseDto.of(
75+
DiaryFixture.createDiaryFixture(1L)
76+
)
77+
);
78+
7279
@DisplayName("성공: 클러스터 캐시 HIT")
7380
@Test
74-
void getDiaryClusters_success_cacheHit() {
81+
void getDiaryClusters_cacheHit() {
7582
// given
76-
given(clusterCacheDao.getDiaryCluster(GEOHASH, VALID_LEVEL_1)).willReturn(Optional.of(mockResult));
83+
given(clusterCacheDao.load(GEOHASH_L3, LEVEL_SIDO)).willReturn(clusters);
7784

7885
// when
79-
List<DiaryClusterResponseDto> result = mapService.getDiaryClusters(GEOHASH, VALID_LEVEL_1);
86+
List<DiaryClusterResponseDto> result = mapService.getDiaryClusters(GEOHASH_L3, LEVEL_SIDO);
8087

8188
// then
82-
assertThat(result).isEqualTo(mockResult);
83-
verify(sidoAreasRepository, never()).findByGeohashPrefix(any());
84-
verify(clusterCacheDao, never()).setDiaryCluster(any(), anyInt(), any(), any());
89+
assertThat(result).isEqualTo(clusters);
90+
verify(clusterCacheDao).load(GEOHASH_L3, LEVEL_SIDO);
91+
verify(clusterCacheDao, never()).loadAndCache(anyString(), anyInt());
8592
}
8693

87-
@DisplayName("성공: 캐시 MISS → DB 조회 → 캐시 저장")
94+
95+
@DisplayName("성공: 캐시 MISS → DAO.loadAndCache 호출")
8896
@Test
89-
void getDiaryClusters_success_cacheMiss_then_dbHit_and_cacheStore() {
97+
void getDiaryClusters_cacheMiss_thenLoadAndCache() {
9098
// given
91-
given(clusterCacheDao.getDiaryCluster(GEOHASH, VALID_LEVEL_1)).willReturn(Optional.empty());
92-
given(sidoAreasRepository.findByGeohashPrefix(GEOHASH)).willReturn(mockResult);
99+
given(clusterCacheDao.load(GEOHASH_L3, LEVEL_SIDO)).willReturn(null);
100+
given(clusterCacheDao.loadAndCache(GEOHASH_L3, LEVEL_SIDO)).willReturn(clusters);
93101

94102
// when
95-
List<DiaryClusterResponseDto> result = mapService.getDiaryClusters(GEOHASH, VALID_LEVEL_1);
103+
List<DiaryClusterResponseDto> result = mapService.getDiaryClusters(GEOHASH_L3, LEVEL_SIDO);
96104

97105
// then
98-
assertThat(result).isEqualTo(mockResult);
99-
verify(clusterCacheDao).setDiaryCluster(eq(GEOHASH), eq(VALID_LEVEL_1), eq(mockResult), any());
100-
}
101-
102-
@DisplayName("실패: 유효하지 않은 level")
103-
@Test
104-
void getDiaryClusters_invalidLevel() {
105-
// given
106-
int invalidLevel = 99;
107-
108-
// expect
109-
assertThatThrownBy(() -> mapService.getDiaryClusters(GEOHASH, invalidLevel))
110-
.isInstanceOf(InvalidMapLevelException.class);
106+
assertThat(result).isEqualTo(clusters);
107+
verify(clusterCacheDao).load(GEOHASH_L3, LEVEL_SIDO);
108+
verify(clusterCacheDao).loadAndCache(GEOHASH_L3, LEVEL_SIDO);
111109
}
112110

113-
@DisplayName("실패: geohash 길이 불일치")
111+
@DisplayName("실패: geohash 길이 불일치(클러스터)")
114112
@Test
115113
void getDiaryClusters_invalidGeohashLength() {
116114
// given
117-
String invalidGeohash = "abcd";
115+
String invalid = "abcd"; // 길이 4 → level(1/2) 기대 길이 3과 불일치
118116

119117
// expect
120-
assertThatThrownBy(() -> mapService.getDiaryClusters(invalidGeohash, VALID_LEVEL_1))
121-
.isInstanceOf(InvalidGeohashException.class)
122-
.hasMessageContaining("geohash 길이가 유효하지 않습니다");
123-
}
124-
125-
@DisplayName("성공 : geohash 캐시 HIT + 모든 diary 캐시 HIT")
126-
@Test
127-
void getDiariesByGeohash_success_allCacheHit() {
128-
// given
129-
String geohash = "wydmt";
130-
Set<Long> cachedIds = Set.of(1L, 2L);
131-
DiaryMarkerResponseDto dto1 = DiaryMarkerFixture.createDiaryMarker(1L);
132-
DiaryMarkerResponseDto dto2 = DiaryMarkerFixture.createDiaryMarker(2L);
133-
134-
given(diaryCacheDao.getDiaryIdSetFromCache("wydmt")).willReturn(cachedIds);
135-
given(diaryCacheDao.getDiariesFromCacheBulk(anyList())).willReturn(List.of(dto1, dto2));
136-
137-
// when
138-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash("wydmt");
139-
140-
// then
141-
assertThat(result).containsExactlyInAnyOrder(dto1, dto2);
142-
verify(diaryRepository, never()).findAllById(any());
143-
verify(diaryGeohashService, never()).getDiaryIdsByGeohash(any());
144-
}
145-
146-
@DisplayName("성공 : geohash 캐시 HIT + 일부 diary 캐시 MISS")
147-
@Test
148-
void getDiariesByGeohash_success_partialDiaryCacheMiss() {
149-
// given
150-
String geohash = "wydmt";
151-
Set<Long> cachedIds = Set.of(1L, 2L);
152-
List<Long> sortedIds = new ArrayList<>(cachedIds);
153-
Collections.sort(sortedIds);
154-
155-
DiaryMarkerResponseDto dto1 = DiaryMarkerFixture.createDiaryMarker(1L);
156-
Diary diary2 = DiaryFixture.createDiaryFixture(2L);
157-
DiaryMarkerResponseDto dto2 = DiaryMarkerResponseDto.of(diary2);
158-
159-
given(diaryCacheDao.getDiaryIdSetFromCache("wydmt")).willReturn(cachedIds);
160-
given(diaryCacheDao.getDiariesFromCacheBulk(anyList()))
161-
.willReturn(List.of(dto1));
162-
given(diaryService.getDiaries(List.of(2L))).willReturn(List.of(diary2));
163-
164-
// when
165-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash("wydmt");
166-
167-
// then
168-
assertThat(result).containsExactlyInAnyOrder(dto1, dto2);
169-
verify(diaryCacheDao).cacheAllDiaries(List.of(dto2));
170-
}
171-
172-
173-
@DisplayName("성공 : geohash 캐시 MISS → DB 조회 → 모든 diary 캐시 HIT")
174-
@Test
175-
void getDiariesByGeohash_success_geohashMiss_allDiaryCacheHit() {
176-
// given
177-
String geohash = "wydmt";
178-
List<Long> diaryIdsFromDb = List.of(1L, 2L);
179-
DiaryMarkerResponseDto dto1 = DiaryMarkerFixture.createDiaryMarker(1L);
180-
DiaryMarkerResponseDto dto2 = DiaryMarkerFixture.createDiaryMarker(2L);
181-
182-
given(diaryCacheDao.getDiaryIdSetFromCache(geohash)).willReturn(Collections.emptySet());
183-
given(diaryGeohashService.getDiaryIdsByGeohash(geohash)).willReturn(diaryIdsFromDb);
184-
given(diaryCacheDao.getDiariesFromCacheBulk(diaryIdsFromDb)).willReturn(List.of(dto1, dto2));
185-
186-
// when
187-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash(geohash);
188-
189-
// then
190-
assertThat(result).containsExactlyInAnyOrder(dto1, dto2);
191-
verify(diaryCacheDao).cacheDiaryIdSetByGeohash(geohash, diaryIdsFromDb);
192-
verify(diaryService, never()).getDiaries(any());
118+
assertThatThrownBy(() -> mapService.getDiaryClusters(invalid, LEVEL_SIDO))
119+
.isInstanceOf(InvalidGeohashException.class);
120+
verifyNoInteractions(clusterCacheDao);
193121
}
194122

195-
@DisplayName("성공 : geohash 캐시 MISS → DB 조회 → 모든 diary 캐시 MISS")
123+
@DisplayName("성공: 마커 캐시 HIT")
196124
@Test
197-
void getDiariesByGeohash_success_geohashMiss_allDiaryCacheMiss() {
125+
void getDiaryMarkers_cacheHit() {
198126
// given
199-
String geohash = "wydmt";
200-
List<Long> diaryIdsFromDb = List.of(1L, 2L);
201-
Diary diary1 = DiaryFixture.createDiaryFixture(1L);
202-
Diary diary2 = DiaryFixture.createDiaryFixture(2L);
203-
DiaryMarkerResponseDto dto1 = DiaryMarkerResponseDto.of(diary1);
204-
DiaryMarkerResponseDto dto2 = DiaryMarkerResponseDto.of(diary2);
205-
206-
given(diaryCacheDao.getDiaryIdSetFromCache(geohash)).willReturn(Collections.emptySet());
207-
given(diaryGeohashService.getDiaryIdsByGeohash(geohash)).willReturn(diaryIdsFromDb);
208-
given(diaryCacheDao.getDiariesFromCacheBulk(diaryIdsFromDb)).willReturn(List.of());
209-
given(diaryService.getDiaries(diaryIdsFromDb)).willReturn(List.of(diary1, diary2));
127+
given(markerCacheDao.load(GEOHASH_L5)).willReturn(markers);
210128

211129
// when
212-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash(geohash);
130+
List<DiaryMarkerResponseDto> result = mapService.getDiaryMarkers(GEOHASH_L5);
213131

214132
// then
215-
assertThat(result).containsExactlyInAnyOrder(dto1, dto2);
216-
verify(diaryCacheDao).cacheDiaryIdSetByGeohash(geohash, diaryIdsFromDb);
217-
verify(diaryCacheDao).cacheAllDiaries(List.of(dto1, dto2));
133+
assertThat(result).isEqualTo(markers);
134+
verify(markerCacheDao).load(GEOHASH_L5);
135+
verify(markerCacheDao, never()).loadAndCache(anyString());
218136
}
219137

220-
@DisplayName("성공 : geohash 캐시 MISS → DB 조회 → diary 일부 캐시 MISS")
138+
@DisplayName("성공: 마커 캐시 MISS → DAO.loadAndCache 호출")
221139
@Test
222-
void getDiariesByGeohash_success_geohashCacheMissAndDiaryCacheMiss() {
140+
void getDiaryMarkers_cacheMiss_thenLoadAndCache() {
223141
// given
224-
String geohash = "abcde";
225-
List<Long> dbIds = List.of(1L, 2L);
226-
DiaryMarkerResponseDto dto1 = DiaryMarkerFixture.createDiaryMarker(1L);
227-
Diary diary2 = DiaryFixture.createDiaryFixture(2L);
228-
DiaryMarkerResponseDto dto2 = DiaryMarkerResponseDto.of(diary2);
229-
230-
given(diaryCacheDao.getDiaryIdSetFromCache(geohash)).willReturn(Collections.emptySet());
231-
given(diaryGeohashService.getDiaryIdsByGeohash(geohash)).willReturn(dbIds);
232-
given(diaryCacheDao.getDiariesFromCacheBulk(dbIds)).willReturn(List.of(dto1));
233-
given(diaryService.getDiaries(List.of(2L))).willReturn(List.of(diary2));
142+
given(markerCacheDao.load(GEOHASH_L5)).willReturn(null);
143+
given(markerCacheDao.loadAndCache(GEOHASH_L5)).willReturn(markers);
234144

235145
// when
236-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash(geohash);
146+
List<DiaryMarkerResponseDto> result = mapService.getDiaryMarkers(GEOHASH_L5);
237147

238148
// then
239-
assertThat(result).containsExactlyInAnyOrder(dto1, dto2);
240-
verify(diaryCacheDao).cacheDiaryIdSetByGeohash(geohash, dbIds);
241-
verify(diaryCacheDao).cacheAllDiaries(List.of(dto2));
149+
assertThat(result).isEqualTo(markers);
150+
verify(markerCacheDao).load(GEOHASH_L5);
151+
verify(markerCacheDao).loadAndCache(GEOHASH_L5);
242152
}
243153

244-
@DisplayName("성공 : Redis 예외 발생 시 fallback 작동: DB에서 조회됨")
154+
@DisplayName("실패: geohash 길이 불일치(마커)")
245155
@Test
246-
void getDiariesByGeohash_redisFailureHandledInternally() {
156+
void getDiaryMarkers_invalidGeohashLength() {
247157
// given
248-
String geohash = "abcde";
249-
given(diaryCacheDao.getDiaryIdSetFromCache(geohash)).willReturn(Collections.emptySet());
250-
251-
List<Long> diaryIds = List.of(1L);
252-
Diary diary = DiaryFixture.createDiaryFixture(1L);
253-
given(diaryGeohashService.getDiaryIdsByGeohash(geohash)).willReturn(diaryIds);
254-
given(diaryService.getDiaries(diaryIds)).willReturn(List.of(diary));
158+
String invalid = "abcd";
255159

256-
// when
257-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash(geohash);
258-
259-
// then
260-
assertThat(result).hasSize(1);
261-
assertThat(result.getFirst().diaryId()).isEqualTo(1L);
262-
verify(diaryService).getDiaries(diaryIds);
263-
}
264-
265-
@DisplayName("예외 : diaryId 존재하나 DB에 diary 없음")
266-
@Test
267-
void diaryIdExistsButDiaryMissingInDb() {
268-
// given
269-
String geohash = "wydmt";
270-
Set<Long> cachedIds = Set.of(100L);
271-
given(diaryCacheDao.getDiaryIdSetFromCache(geohash)).willReturn(cachedIds);
272-
given(diaryCacheDao.getDiariesFromCacheBulk(List.of(100L))).willReturn(List.of());
273-
given(diaryService.getDiaries(List.of(100L))).willReturn(Collections.emptyList());
274-
275-
// when
276-
List<DiaryMarkerResponseDto> result = mapService.getDiariesByGeohash(geohash);
277-
278-
// then
279-
assertThat(result).isEmpty();
160+
// expect
161+
assertThatThrownBy(() -> mapService.getDiaryMarkers(invalid))
162+
.isInstanceOf(InvalidGeohashException.class);
163+
verifyNoInteractions(markerCacheDao);
280164
}
281-
282165
}

0 commit comments

Comments
 (0)