Skip to content

Commit b67b119

Browse files
committed
chore: 테스트 및 설정 코드 정리
- 미사용 메서드 제거 (KafkaTopicRouter.isValidTopic) - AsyncConfig 반환 타입 명확화 - KafkaConfig 키 타입 String으로 변경 - 테스트 코드 개선
1 parent d049e64 commit b67b119

7 files changed

Lines changed: 28 additions & 31 deletions

File tree

apps/commerce-api/src/main/java/com/loopers/config/AsyncConfig.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.springframework.scheduling.annotation.Scheduled;
1111
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
1212

13-
import java.util.concurrent.Executor;
1413
import java.util.concurrent.ThreadPoolExecutor;
1514

1615
/**
@@ -35,7 +34,7 @@ public class AsyncConfig implements AsyncConfigurer {
3534
*/
3635
@Bean(name = "taskExecutor")
3736
@Override
38-
public Executor getAsyncExecutor() {
37+
public ThreadPoolTaskExecutor getAsyncExecutor() {
3938
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
4039
executor.setCorePoolSize(10); // 5 → 10
4140
executor.setMaxPoolSize(20); // 10 → 20

apps/commerce-api/src/main/java/com/loopers/infrastructure/kafka/KafkaTopicRouter.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,4 @@ public String getTopicName(String eventType) {
3737
};
3838
}
3939

40-
/**
41-
* 토픽 이름이 유효한지 검증
42-
*/
43-
public boolean isValidTopic(String topicName) {
44-
return topicName != null &&
45-
topicName.startsWith(TOPIC_PREFIX) &&
46-
topicName.endsWith(TOPIC_VERSION);
47-
}
4840
}

apps/commerce-api/src/test/java/com/loopers/application/event/integration/OrderPaymentEventIntegrationTest.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.springframework.context.ApplicationEventPublisher;
2626
import org.springframework.test.context.event.ApplicationEvents;
2727
import org.springframework.test.context.event.RecordApplicationEvents;
28-
import org.springframework.transaction.annotation.Transactional;
28+
import org.springframework.transaction.support.TransactionTemplate;
2929

3030
import java.time.LocalDateTime;
3131
import java.util.List;
@@ -69,14 +69,17 @@ class OrderPaymentEventIntegrationTest {
6969
@Autowired
7070
private DatabaseCleanUp databaseCleanUp;
7171

72+
@Autowired
73+
private TransactionTemplate transactionTemplate;
74+
7275
private Member testMember;
7376
private Product testProduct;
7477
private Order testOrder;
7578

7679
@BeforeEach
7780
void setUp() {
7881
// 테스트 회원 생성
79-
testMember = new Member("test-user", "test@example.com", "password123", "1990-01-01", Gender.MALE);
82+
testMember = new Member("testuser", "test@example.com", "password123", "1990-01-01", Gender.MALE);
8083
testMember = memberRepository.save(testMember);
8184

8285
// 테스트 상품 생성 (재고 100개)
@@ -92,7 +95,6 @@ void setUp() {
9295
testProduct.decreaseStock(5);
9396
productRepository.save(testProduct);
9497

95-
entityManager.flush();
9698
entityManager.clear();
9799
}
98100

@@ -103,7 +105,6 @@ void tearDown() {
103105

104106
@Test
105107
@DisplayName("결제 성공 시 주문 상태가 PAID로 변경되고 OrderCompletedEvent가 발행된다")
106-
@Transactional
107108
void 결제_성공_시_주문_완료() {
108109
// given
109110
String orderNo = testOrder.getOrderNo();
@@ -118,7 +119,7 @@ void tearDown() {
118119
);
119120

120121
// when
121-
eventPublisher.publishEvent(paymentEvent);
122+
transactionTemplate.executeWithoutResult(status -> eventPublisher.publishEvent(paymentEvent));
122123

123124
// 비동기 처리 대기 (최대 3초)
124125
await().atMost(3, TimeUnit.SECONDS).untilAsserted(() -> {
@@ -139,7 +140,6 @@ void tearDown() {
139140

140141
@Test
141142
@DisplayName("결제 실패 시 주문이 취소되고 재고가 복구된다")
142-
@Transactional
143143
void 결제_실패_시_주문_취소_및_재고_복구() {
144144
// given
145145
String orderNo = testOrder.getOrderNo();
@@ -160,7 +160,7 @@ void tearDown() {
160160
);
161161

162162
// when
163-
eventPublisher.publishEvent(paymentEvent);
163+
transactionTemplate.executeWithoutResult(status -> eventPublisher.publishEvent(paymentEvent));
164164

165165
// 비동기 처리 대기
166166
await().atMost(3, TimeUnit.SECONDS).untilAsserted(() -> {
@@ -179,13 +179,11 @@ void tearDown() {
179179

180180
@Test
181181
@DisplayName("이미 결제 완료된 주문에 중복 이벤트 발행 시 멱등성 보장")
182-
@Transactional
183182
void 중복_이벤트_멱등성_보장() {
184183
// given - 주문을 먼저 PAID 상태로 변경
185184
String orderNo = testOrder.getOrderNo();
186185
testOrder.markAsPaid();
187186
orderRepository.save(testOrder);
188-
entityManager.flush();
189187
entityManager.clear();
190188

191189
PaymentCompletedEvent paymentEvent = new PaymentCompletedEvent(
@@ -197,7 +195,7 @@ void tearDown() {
197195
);
198196

199197
// when - 중복 이벤트 발행
200-
eventPublisher.publishEvent(paymentEvent);
198+
transactionTemplate.executeWithoutResult(status -> eventPublisher.publishEvent(paymentEvent));
201199

202200
// 비동기 처리 대기
203201
await().atMost(3, TimeUnit.SECONDS).pollInterval(100, TimeUnit.MILLISECONDS).untilAsserted(() -> {
@@ -228,7 +226,7 @@ void tearDown() {
228226
);
229227

230228
// when
231-
eventPublisher.publishEvent(paymentEvent);
229+
transactionTemplate.executeWithoutResult(status -> eventPublisher.publishEvent(paymentEvent));
232230

233231
// 비동기 처리 및 트랜잭션 커밋 대기
234232
await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> {

apps/commerce-api/src/test/java/com/loopers/domain/order/OrderPlacementServiceTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.loopers.domain.product.InMemoryProductRepository;
1616
import com.loopers.domain.product.Product;
1717
import com.loopers.domain.product.vo.Stock;
18+
import com.loopers.infrastructure.cache.CacheInvalidationService;
1819
import com.loopers.support.TestEntityUtils;
1920
import com.loopers.support.error.CoreException;
2021
import org.junit.jupiter.api.BeforeEach;
@@ -26,6 +27,7 @@
2627
import java.util.List;
2728

2829
import static org.assertj.core.api.Assertions.*;
30+
import static org.mockito.Mockito.mock;
2931

3032
class OrderPlacementServiceTest {
3133

@@ -34,6 +36,7 @@ class OrderPlacementServiceTest {
3436
private InMemoryMemberRepository memberRepository;
3537
private InMemoryPointRepository pointRepository;
3638
private InMemoryMemberCouponRepository memberCouponRepository;
39+
private CacheInvalidationService cacheInvalidationService;
3740
private OrderPlacementService orderPlacementService;
3841
private long memberSequence;
3942

@@ -44,12 +47,14 @@ void setUp() {
4447
memberRepository = new InMemoryMemberRepository();
4548
pointRepository = new InMemoryPointRepository();
4649
memberCouponRepository = new InMemoryMemberCouponRepository();
50+
cacheInvalidationService = mock(CacheInvalidationService.class);
4751
memberSequence = 0L;
4852
orderPlacementService = new OrderPlacementService(
4953
orderRepository,
5054
productRepository,
5155
memberRepository,
52-
memberCouponRepository
56+
memberCouponRepository,
57+
cacheInvalidationService
5358
);
5459
}
5560

apps/commerce-api/src/test/java/com/loopers/infrastructure/kafka/KafkaConnectionTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import org.junit.jupiter.api.DisplayName;
44
import org.junit.jupiter.api.Test;
55
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
7+
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
68
import org.springframework.boot.test.context.SpringBootTest;
79
import org.springframework.kafka.core.KafkaTemplate;
810
import org.springframework.kafka.support.SendResult;
@@ -24,6 +26,7 @@
2426
"spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer"
2527
}
2628
)
29+
@ImportAutoConfiguration(JacksonAutoConfiguration.class)
2730
@ActiveProfiles("test")
2831
class KafkaConnectionTest {
2932

@@ -62,7 +65,7 @@ void kafkaProducerAcksConfigTest() {
6265

6366
// then
6467
assertThat(configs.get("acks")).isEqualTo("all");
65-
assertThat(configs.get("enable.idempotence")).isEqualTo(true);
68+
assertThat(Boolean.parseBoolean(String.valueOf(configs.get("enable.idempotence")))).isTrue();
6669

6770
System.out.println("✅ Producer 설정 확인:");
6871
System.out.println("acks: " + configs.get("acks"));

modules/kafka/src/main/java/com/loopers/confg/kafka/KafkaConfig.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ public class KafkaConfig {
3030
public static final int MAX_POLL_INTERVAL_MS = 2 * 60 * 1000; // max poll interval = 2m
3131

3232
@Bean
33-
public ProducerFactory<Object, Object> producerFactory(KafkaProperties kafkaProperties) {
33+
public ProducerFactory<String, Object> producerFactory(KafkaProperties kafkaProperties) {
3434
Map<String, Object> props = new HashMap<>(kafkaProperties.buildProducerProperties());
3535
return new DefaultKafkaProducerFactory<>(props);
3636
}
3737

3838
@Bean
39-
public ConsumerFactory<Object, Object> consumerFactory(KafkaProperties kafkaProperties) {
39+
public ConsumerFactory<String, Object> consumerFactory(KafkaProperties kafkaProperties) {
4040
Map<String, Object> props = new HashMap<>(kafkaProperties.buildConsumerProperties());
4141
return new DefaultKafkaConsumerFactory<>(props);
4242
}
4343

4444
@Bean
45-
public KafkaTemplate<Object, Object> kafkaTemplate(ProducerFactory<Object, Object> producerFactory) {
45+
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> producerFactory) {
4646
return new KafkaTemplate<>(producerFactory);
4747
}
4848

@@ -52,7 +52,7 @@ public ByteArrayJsonMessageConverter jsonMessageConverter(ObjectMapper objectMap
5252
}
5353

5454
@Bean(name = BATCH_LISTENER)
55-
public ConcurrentKafkaListenerContainerFactory<Object, Object> defaultBatchListenerContainerFactory(
55+
public ConcurrentKafkaListenerContainerFactory<String, Object> defaultBatchListenerContainerFactory(
5656
KafkaProperties kafkaProperties,
5757
ByteArrayJsonMessageConverter converter
5858
) {
@@ -64,7 +64,7 @@ public ConcurrentKafkaListenerContainerFactory<Object, Object> defaultBatchListe
6464
consumerConfig.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, HEARTBEAT_INTERVAL_MS);
6565
consumerConfig.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, MAX_POLL_INTERVAL_MS);
6666

67-
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
67+
ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
6868
factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(consumerConfig));
6969
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); // 수동 커밋
7070
factory.setBatchMessageConverter(new BatchMessagingMessageConverter(converter));

modules/redis/src/testFixtures/java/com/loopers/testcontainers/RedisTestContainersConfig.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ public class RedisTestContainersConfig {
1010

1111
static {
1212
redisContainer.start();
13-
}
14-
15-
public RedisTestContainersConfig() {
1613
System.setProperty("datasource.redis.database", "0");
1714
System.setProperty("datasource.redis.master.host", redisContainer.getHost());
1815
System.setProperty("datasource.redis.master.port", String.valueOf(redisContainer.getFirstMappedPort()));
1916
System.setProperty("datasource.redis.replicas[0].host", redisContainer.getHost());
2017
System.setProperty("datasource.redis.replicas[0].port", String.valueOf(redisContainer.getFirstMappedPort()));
2118
}
19+
20+
public RedisTestContainersConfig() {
21+
}
2222
}

0 commit comments

Comments
 (0)