Skip to content

Commit fd11c00

Browse files
committed
test: RankingWeightTest 클래스 추가 및 가중치 관련 기능 테스트 구현
1 parent b99c7b9 commit fd11c00

1 file changed

Lines changed: 189 additions & 0 deletions

File tree

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package com.loopers.domain.ranking;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.DisplayName;
5+
import org.junit.jupiter.api.Nested;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.ExtendWith;
8+
import org.mockito.Mock;
9+
import org.mockito.junit.jupiter.MockitoExtension;
10+
import org.springframework.data.redis.core.HashOperations;
11+
import org.springframework.data.redis.core.RedisTemplate;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
import static org.assertj.core.api.Assertions.within;
15+
import static org.mockito.Mockito.*;
16+
17+
@ExtendWith(MockitoExtension.class)
18+
class RankingWeightTest {
19+
20+
@Mock
21+
private RedisTemplate<String, String> redisTemplate;
22+
23+
@Mock
24+
private HashOperations<String, Object, Object> hashOperations;
25+
26+
private RankingWeight rankingWeight;
27+
28+
private static final String WEIGHT_KEY = "ranking:config:weights";
29+
30+
@BeforeEach
31+
void setUp() {
32+
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
33+
rankingWeight = new RankingWeight(redisTemplate);
34+
}
35+
36+
@Nested
37+
@DisplayName("가중치 반환")
38+
class GetWeight {
39+
40+
@Test
41+
@DisplayName("Redis에 값이 있으면 해당 값을 반환한다")
42+
void shouldReturnRedisValueWhenExists() {
43+
// given
44+
when(hashOperations.get(WEIGHT_KEY, "view")).thenReturn("0.15");
45+
46+
// when
47+
double weight = rankingWeight.getViewWeight();
48+
49+
// then
50+
assertThat(weight).isEqualTo(0.15);
51+
}
52+
53+
@Test
54+
@DisplayName("Redis에 값이 없으면 기본값을 반환한다")
55+
void shouldReturnDefaultWhenRedisValueIsNull() {
56+
// given
57+
when(hashOperations.get(WEIGHT_KEY, "view")).thenReturn(null);
58+
59+
// when
60+
double weight = rankingWeight.getViewWeight();
61+
62+
// then
63+
assertThat(weight).isEqualTo(0.1); // DEFAULT_VIEW_WEIGHT
64+
}
65+
66+
@Test
67+
@DisplayName("Redis 예외 발생 시 기본값을 반환한다")
68+
void shouldReturnDefaultWhenRedisThrowsException() {
69+
// given
70+
when(hashOperations.get(WEIGHT_KEY, "like")).thenThrow(new RuntimeException("Redis error"));
71+
72+
// when
73+
double weight = rankingWeight.getLikeWeight();
74+
75+
// then
76+
assertThat(weight).isEqualTo(0.2); // DEFAULT_LIKE_WEIGHT
77+
}
78+
}
79+
80+
@Nested
81+
@DisplayName("가중치 계산")
82+
class CalculateScore {
83+
84+
@Test
85+
@DisplayName("조회 점수 계산: viewWeight * 1.0")
86+
void shouldCalculateViewScore() {
87+
// given
88+
when(hashOperations.get(WEIGHT_KEY, "view")).thenReturn("0.1");
89+
90+
// when
91+
double score = rankingWeight.calculateViewScore();
92+
93+
// then
94+
assertThat(score).isEqualTo(0.1);
95+
}
96+
97+
@Test
98+
@DisplayName("좋아요 점수 계산: likeWeight * 1.0 (좋아요)")
99+
void shouldCalculateLikeScoreWhenLiked() {
100+
// given
101+
when(hashOperations.get(WEIGHT_KEY, "like")).thenReturn("0.2");
102+
103+
// when
104+
double score = rankingWeight.calculateLikeScore(true);
105+
106+
// then
107+
assertThat(score).isEqualTo(0.2);
108+
}
109+
110+
@Test
111+
@DisplayName("좋아요 취소 점수 계산: likeWeight * -1.0 (취소)")
112+
void shouldCalculateNegativeScoreWhenUnliked() {
113+
// given
114+
when(hashOperations.get(WEIGHT_KEY, "like")).thenReturn("0.2");
115+
116+
// when
117+
double score = rankingWeight.calculateLikeScore(false);
118+
119+
// then
120+
assertThat(score).isEqualTo(-0.2);
121+
}
122+
123+
@Test
124+
@DisplayName("주문 점수 계산 (수량 기반): orderWeight * quantity")
125+
void shouldCalculateOrderScoreWithQuantity() {
126+
// given
127+
when(hashOperations.get(WEIGHT_KEY, "order")).thenReturn("0.7");
128+
129+
// when
130+
double score = rankingWeight.calculateOrderScore(5);
131+
132+
// then
133+
assertThat(score).isEqualTo(3.5); // 0.7 * 5
134+
}
135+
136+
@Test
137+
@DisplayName("주문 점수 계산 (금액 기반): orderWeight * log10(amount)")
138+
void shouldCalculateOrderScoreWithAmount() {
139+
// given
140+
when(hashOperations.get(WEIGHT_KEY, "order")).thenReturn("0.7");
141+
142+
// when
143+
double score = rankingWeight.calculateOrderScoreWithAmount(10000L);
144+
145+
// then
146+
// 0.7 * log10(10000) = 0.7 * 4 = 2.8
147+
assertThat(score).isCloseTo(2.8, within(0.01));
148+
}
149+
150+
@Test
151+
@DisplayName("금액이 0 이하일 때 점수는 0이다")
152+
void shouldReturnZeroScoreWhenAmountIsZeroOrNegative() {
153+
// when
154+
double scoreZero = rankingWeight.calculateOrderScoreWithAmount(0);
155+
double scoreNegative = rankingWeight.calculateOrderScoreWithAmount(-100);
156+
157+
// then
158+
assertThat(scoreZero).isEqualTo(0);
159+
assertThat(scoreNegative).isEqualTo(0);
160+
}
161+
}
162+
163+
@Nested
164+
@DisplayName("가중치 업데이트")
165+
class UpdateWeights {
166+
167+
@Test
168+
@DisplayName("모든 가중치를 일괄 업데이트한다")
169+
void shouldUpdateAllWeights() {
170+
// when
171+
rankingWeight.updateAllWeights(0.15, 0.25, 0.6);
172+
173+
// then
174+
verify(hashOperations).put(WEIGHT_KEY, "view", "0.15");
175+
verify(hashOperations).put(WEIGHT_KEY, "like", "0.25");
176+
verify(hashOperations).put(WEIGHT_KEY, "order", "0.6");
177+
}
178+
179+
@Test
180+
@DisplayName("가중치 초기화 시 Redis 키를 삭제한다")
181+
void shouldDeleteKeyWhenReset() {
182+
// when
183+
rankingWeight.resetToDefault();
184+
185+
// then
186+
verify(redisTemplate).delete(WEIGHT_KEY);
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)