@Transactional 차이로 인해 재고의 quantity 가 감소되지 않는 이유에 대해 질문 드립니다.
329
작성자 없음
안녕하세요, 강사님 테스트에 관심이 생겼고, 강사님 덕분에 테스트에 대해 하나하나 알아가는 재미를 느끼는 중입니다!
좋은 강의 감사드립니다!
강의를 진행하던 도중 의문이 있어서 질문 드립니다.
문제 상황입니다.
stock.deductQuantity(quantity) 부분에서 stock 의 this.quantity 가 파라미터로 들어온 quantity 만큼 갯수가 감소되는 것을 확인하였습니다. (아래 사진에 빨간줄로 밑줄 그었습니다)


그러나, 테스트의 결과는 실패로 떴습니다.
그 이유는 감소된 재고의 수량(Stock 의 quantity)이 아래 사진처럼 테스트에 반영되지 않았습니다.

해당 테스트 코드입니다. 강사님의 테스트 코드와 일치하게 짰습니다.
@DisplayName("재고와 관련된 상품이 포함되어 있는 주문번호 리스트를 받아 주문을 생성한다.")
@Test
void createOrderWithStock() {
// given
Product product1 = createProduct(BOTTLE, "001", 1000);
Product product2 = createProduct(BAKERY, "002", 3000);
Product product3 = createProduct(HANDMADE, "003", 5000);
productRepository.saveAll(List.of(product1, product2, product3));
Stock stock1 = Stock.create("001", 2);
Stock stock2 = Stock.create("002", 2);
stockRepository.saveAll(List.of(stock1, stock2));
OrderAddRequest request = OrderAddRequest.builder()
.productNumbers(List.of("001", "001", "003", "002"))
.build();
LocalDateTime registeredDateTime = LocalDateTime.now();
// when
OrderResponse orderResponse = orderService.createOrder(request, registeredDateTime);
// then
assertThat(orderResponse.getId()).isNotNull();
assertThat(orderResponse)
.extracting("registeredDateTime", "totalPrice")
.contains(registeredDateTime, 10000);
assertThat(orderResponse.getProducts()).hasSize(4)
.extracting("productNumber", "price")
.containsExactlyInAnyOrder(
tuple("001", 1000),
tuple("001", 1000),
tuple("002", 3000),
tuple("003", 5000)
);
List<Stock> stocks = stockRepository.findAll();
assertThat(stocks).hasSize(2)
.extracting("productNumber", "quantity")
.containsExactlyInAnyOrder(
tuple("001", 0),
tuple("002", 1)
);
}
왜 테스트가 실패하는지 한참 헤매다가 OrderService 에 @Transactional 을 추가하였더니 Stock의 감소된 quantity 가 테스트에 반영이 되었고, 테스트가 성공하게 되었습니다.
// OrderService 중 일부 발췌
@Transactional
@RequiredArgsConstructor
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final ProductRepository productRepository;
private final StockRepository stockRepository;
저의 얕은 지식으로는 @Transactional 이 왜 테스트에 영향을 주게 되었는지 이해가 도통되지 않아 강사님께 질문을 드립니다
답변 2
0
안녕하세요!
해당 현상은 테스트 코드와는 조금 무관한데요 ㅎㅎ
강의 중에도 언급하지만, JPA의 변경 감지 기능에 대해서 학습해보시면 좋을 것 같습니다.
JPA의 변경 감지를 통해 update 쿼리가 생성되는 작업은 트랜잭션 범위 내에서 이루어집니다.
감사합니다 🙂
0
안녕하세요, 인프런 AI 인턴입니다.
종혁님의 질문은 @Transactional 어노테이션의 부재로 인해 재고 수량 감소가 테스트에 반영되지 않는 원인에 관한 것으로 보입니다. 이와 관련하여, @Transactional을 붙였을 때만 Stock 감소 검증에 성공합니다라는 질문에 대한 답을 찾을 수 있을 것 같습니다.
해당 답변 URL은 여기에서 확인하실 수 있습니다. 질문에 제시된 상황과 유사하게, @Transactional을 사용하거나 사용하지 않음에 따라 stock의 quantity 감소를 검증하는 테스트에서 차이가 발생할 수 있음을 논의하고 있습니다. 질문자는 stock의 quantity 감소 로직에 @Transactional 어노테이션을 추가한 후 테스트가 성공했다고 언급하는데, 이는 stock 상태의 변경이 정상적으로 데이터베이스에 반영되어 테스트 내에서 검증될 수 있음을 의미합니다.
요약:
@Transactional어노테이션은 테스트 내에서 데이터베이스 상태의 변경을 영속화하기 위해 필요합니다.
- 이 어노테이션은 테스트가 실행되는 동안 일어나는 변화(예: stock quantity의 감소)를 데이터베이스에 커밋하여 영속적인 상태 변화를 보장합니다. 이로 인해 해당 변경사항을 다시 조회하거나 검증할 때 올바르게 반영됩니다.
- 어노테이션을 추가하지 않는 경우, 테스트 종료 시 모든 변경사항이 롤백되어 테스트를 올바르게 검증할 수 없습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
private 상수 테스트 관련 질문
0
112
1
void는 어떻게 테스트하나요..? void로 애초에 코딩하면 안되나요??
0
157
2
커버리지는 어떻게 활용하시는지 궁금합니다.
0
194
2
테스트 문서화 질문입니다
0
129
2
단위테스트 질문이 있습니다
0
106
2
컨트롤러는 모킹을 한 이유가 궁금합니다.
0
118
2
ERD 가장자리에 있는 도메인 테스트 질문
0
106
2
DTO 검증 필드에 대한 테스트 코드 작성은 어디까지?
0
146
2
OrderCreateRequest DTO에 대해서 궁금한점
0
112
2
고전파의 테스트 대역 사용 대상, 공유 의존성
0
167
2
계층 관련 질문이 있습니다.
0
159
3
'코틀린'에서는 빌더를 따로 쓰지 않는데, 이 때는 어떻게 test fixture를 만드시는지 궁금합니다
1
136
2
혹시 update 로직은 어떻게 테스트하나요? (@Setter?)
0
146
2
단위테스트와 통합테스트의 경계가 궁금합니다.
0
257
2
Service+Repository 통합테스트 관련 질문입니다.
0
169
2
OrderControllerDocsTest 작성 해봤는데요. 날짜 형식이 이상하게 나와요
0
201
2
test 용 .yml
0
105
2
throws Exception
0
87
2
카페키오스크 클래스 문의 ,,
0
100
2
Rest docs 문서용 테스트코드를 따로 작성해야 되나요?
0
188
2
테스트 코드에서 필요한 생성자
0
145
1
tearDown 순서
0
122
2
@Builder 생성자 private
0
147
2
@DisplayName gradle / intellJ
0
99
2





