์ค๋ ์งํํ ๋ด์ฉ๋ค ๐ง
Elasticsearch ๊ธฐ๊ฐ ๊ฒ์ ์กฐํ ์ฑ๋ฅ ๋น๊ตํ๊ธฐ
hiringStartAt๊ณผ hiringEndAt์ ํตํด ์ฑ์ฉ ๊ณต๊ณ ๋ฅผ ์กฐํํ๋ ๊ธฐ๋ฅ์ Elasticsearch๋ฅผ ์ ์ฉํ์ ๋ ์ฑ๋ฅ์ด ์ผ๋ง๋ ํฅ์๋๋์ง ํ์ธํด๋ดค๋ค.
Elasticsearch๋ฅผ ์ ์ฉํ๊ธฐ ์ ํ์ ์๋๋ฅผ JMeter๋ฅผ ์ด์ฉํ์ฌ ์ฑ๋ฅ์ ๋น๊ตํด ๋ณด์๋ค.
100๊ฐ์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๊ณ , 10์ด ๋์ 10ํ๋ฅผ ์คํํ์ฌ ์ด 1,000๊ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํ
์คํธ๋ฅผ ์งํํ๋ค.
Elasticsearch ์ ์ฉํ๊ธฐ ์ ํ ์๋๊ฐ ์ฐจ์ด๊ฐ ๋์ ๋๊ฒ ์ค์ด๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค. ์ ์ฉํ๊ธฐ ์ ์๋ 8ms์๋๋ฐ, Elasticsearch๋ฅผ ์ ์ฉํ๊ณ ๋๋ 1ms๊น์ง ๋จ์ด์ก๋ค.
ํ ์คํธ ์ฝ๋ ๊ณต๋ถํ๊ธฐ
์์ง ๊ณผ์ ์์ ์์ ํ๋ ๊ฒ๋ง ํด๋ณด๊ณ ์ค์ ๋ก ๋ด๊ฐ ์ง์ ํ ์คํธ ์ฝ๋๋ฅผ ์ง๋ณธ ๊ฒฝํ์ด ์์ด์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ๊ด๋ จ ๊ฐ๋ ๋ค์ ๊ณต๋ถํ๋ค. @Mock, @InjectMocks์ ๊ฐ์ ์ด๋ ธํ ์ด์ ์ ๋ํด ๊ณต๋ถํ๊ณ when์ ์ฌ์ฉํ์ ๋ ์ฝ๋๋ฅผ ์ด๋ค ์์ผ๋ก ์์ฑํด์ผ ํ๋์ง ํ์ธํ๋ค.
historyscheduler ํ ์คํธ ์ฝ๋ ์์ฑํ๊ธฐ
@ExtendWith(MockitoExtension.class)
public class historySchedulerTest {
@InjectMocks
private HistoryScheduler historyScheduler;
@Mock
private HistoryRepository historyRepository;
@Mock
private UserFindByService userFindByService;
@Mock
private RedisTemplate<String, String> redisTemplate;
@Mock
private ZSetOperations<String, String> zSetOperations;
@Test
void saveSearchHistoryToDb_์ ์์ ์ผ๋ก_๋์ํ _๊ฒฝ์ฐ() {
// given
String key = "user:1:search_history";
Set<String> keys = Set.of(key);
Set<String> searchTerms = Set.of("Redis", "Java");
when(redisTemplate.keys("user:*:search_history")).thenReturn(keys);
when(redisTemplate.opsForZSet()).thenReturn(zSetOperations);
when(zSetOperations.range(key, 0, -1)).thenReturn(searchTerms);
User mockUser = User.of(
"test@example.com",
"testUser",
25,
3,
"password123"
);
when(userFindByService.findById(1L)).thenReturn(mockUser);
when(historyRepository.existsByUserIdAndName(1L, "Redis")).thenReturn(false);
when(historyRepository.existsByUserIdAndName(1L, "Java")).thenReturn(true);
// when
historyScheduler.saveSearchHistoryToDb();
// then
verify(historyRepository,times(1)).save(any(History.class));
}
@Test
void saveSearchHistoryToDb_์ ์ฅํ _๊ฒ์์ด๊ฐ_์์_๊ฒฝ์ฐ() {
// given
String key = "user:1:search_history";
Set<String> keys = Set.of(key);
when(redisTemplate.keys("user:*:search_history")).thenReturn(keys);
when(redisTemplate.opsForZSet()).thenReturn(zSetOperations);
when(zSetOperations.range(key, 0, -1)).thenReturn(Collections.emptySet());
// when
historyScheduler.saveSearchHistoryToDb();
// then
verify(historyRepository, never()).save(any(History.class));
}
@Test
void saveSearchHistoryToDb_์ ์ ๊ฐ_์์_๊ฒฝ์ฐ_์์ธ_๋ฐ์() {
// given
String key = "user:99:search_history";
Set<String> keys = Set.of(key);
when(redisTemplate.keys("user:*:search_history")).thenReturn(keys);
when(userFindByService.findById(99L)).thenThrow(new NotFoundException(DataErrorCode.USER_NOT_FOUND));
// when & then
NotFoundException exception = assertThrows(NotFoundException.class, () -> historyScheduler.saveSearchHistoryToDb());
assertEquals(DataErrorCode.USER_NOT_FOUND.getMessage(), exception.getMessage());
verify(historyRepository, never()).save(any(History.class));
}
}
์ค๋ ํ๋ฃจ ์ ๋ฆฌ โ๏ธ
ํ
์คํธ ์ฝ๋์ ๋ํด ๊ณต๋ถํ๋ค ๋ณด๋ ์ฝ๊ฐ ์ดํด๋ฅผ ํ ์ ์์ ์ ๋๊น์ง ์ดํด๋ ฅ์ด ์ฌ๋ผ์จ ๊ฒ ๊ฐ๋ค.
์์ง ๊ณต๋ถํด์ผ ํ ๊ฒ๋ค์ด ์ฐ๋๋ฏธ์ฒ๋ผ ์์ฌ์๋ค.
๋ด์ผ ๊ณํ โฐ
- V3 ํ์ํ๊ธฐ
- Elasticsearch API ์ฐ๋ํ๋ ๋ฐฉ๋ฒ ํํฐ๋๊ป ์ฐพ์๊ฐ๊ธฐ
+ ์ถ๊ฐ ๊ณํ์ด ๋ ์๊ธธ ์๋ ์์ต๋๋ค!
'โ๏ธ Today I Learned(TIL) > ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ TIL ] ์ต์ข ํ๋ก์ ํธ_Day 15 (0) | 2025.02.25 |
---|---|
[ TIL ] ์ต์ข ํ๋ก์ ํธ_Day 14 (0) | 2025.02.24 |
[ TIL ] ์ต์ข ํ๋ก์ ํธ_Day 10 (0) | 2025.02.19 |
[ TIL ] ์ต์ข ํ๋ก์ ํธ_Day 9 (0) | 2025.02.19 |
[ TIL ] ์ต์ข ํ๋ก์ ํธ_Day 8 (0) | 2025.02.18 |