해결된 질문
작성
·
352
·
수정됨
0
안녕하세요 강사님. 프로젝트 진행중에 간단한 테스트 작업 중 이상한 결과가 나와서 질문드립니다..!
@Transactional
@SpringBootTest
@ActiveProfiles("test")
class ProductListResponseDtoTest {
@Autowired ProductRepository productRepository;
@Test
@DisplayName("주문 상세가 주어졌을 때 ProductListResponseDto 변환")
public void ofWithOrderDetail() {
Product product = Product.builder()
.price(1000L)
.name("빵빵이")
.productNo("123")
.build();
productRepository.save(product);
OrderDetail orderDetail = OrderDetail.builder()
.product(product)
.price(product.getPrice())
.quantity(2L)
.build();
// when
ProductListResponseDto result = ProductListResponseDto.of(orderDetail);
// then
assertThat(result).extracting("productId", "productNo", "name", "price", "quantity")
.contains(1L, "123", "빵빵이", 1000L, 2L);
}
@Test
@DisplayName("상품과 수량이 주어졌을 때 ProductListResponseDto 변환")
public void ofWithProductAndQuantity() {
Long quantity = 2L;
Product product = Product.builder()
.price(1000L)
.name("빵빵이")
.productNo("123")
.build();
productRepository.save(product);
// when
ProductListResponseDto result = ProductListResponseDto.of(product, quantity);
// then
assertThat(result).extracting("productId", "productNo", "name", "price", "quantity")
.contains(1L, "123", "빵빵이", 1000L, 2L);
}
}
@Transactional를 통해 각 테스트가 롤백되어 productId가 모두 1L 될 것으로 예상하였습니다.
그런데 기대와 달리 실패를 하였는데요. 첫번째 테스트(ofWithOrderDetail)의 productId의 값이 2L 되었습니다.
insert문과 에러 메세지입니다.
Hibernate:
insert
into
product
(category_id, created_at, deleted_at, discount_rate, is_own, is_subs, name, price, product_no, stock, thumb_img, updated_at, product_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, default)
2024-01-29T22:28:07.219+09:00 INFO 3636 --- [ main] p6spy : #1706534887219 | took 4ms | statement | connection 3| url jdbc:h2:mem:~/Marketbridge
insert into product (category_id,created_at,deleted_at,discount_rate,is_own,is_subs,name,price,product_no,stock,thumb_img,updated_at,product_id) values (?,?,?,?,?,?,?,?,?,?,?,?,default)
insert into product (category_id,created_at,deleted_at,discount_rate,is_own,is_subs,name,price,product_no,stock,thumb_img,updated_at,product_id) values (NULL,NULL,NULL,NULL,NULL,NULL,'빵빵이',1000,'123',NULL,NULL,NULL,default);
2024-01-29T22:28:07.299+09:00 INFO 3636 --- [ main] p6spy : #1706534887299 | took 0ms | rollback | connection 3| url jdbc:h2:mem:~/Marketbridge
;
Hibernate:
insert
into
product
(category_id, created_at, deleted_at, discount_rate, is_own, is_subs, name, price, product_no, stock, thumb_img, updated_at, product_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, default)
2024-01-29T22:28:07.309+09:00 INFO 3636 --- [ main] p6spy : #1706534887309 | took 0ms | statement | connection 4| url jdbc:h2:mem:~/Marketbridge
insert into product (category_id,created_at,deleted_at,discount_rate,is_own,is_subs,name,price,product_no,stock,thumb_img,updated_at,product_id) values (?,?,?,?,?,?,?,?,?,?,?,?,default)
insert into product (category_id,created_at,deleted_at,discount_rate,is_own,is_subs,name,price,product_no,stock,thumb_img,updated_at,product_id) values (NULL,NULL,NULL,NULL,NULL,NULL,'빵빵이',1000,'123',NULL,NULL,NULL,default);
2024-01-29T22:28:07.317+09:00 INFO 3636 --- [ main] p6spy : #1706534887317 | took 0ms | rollback | connection 4| url jdbc:h2:mem:~/Marketbridge
;
java.lang.AssertionError: [Extracted: productId, productNo, name, price, quantity]
Expecting ArrayList:
[2L, "123", "빵빵이", 1000L, 2L]
to contain:
[1L, "123", "빵빵이", 1000L, 2L]
but could not find the following element(s):
[1L]
at com.objects.marketbridge.order.service.dto.ProductListResponseDtoTest.ofWithOrderDetail(ProductListResponseDtoTest.java:44)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
of 메서드 입니다.
@Getter
public class ProductListResponseDto {
private Long productId;
private String productNo;
private String name;
private Long price;
private Long quantity;
@Builder
private ProductListResponseDto(Long productId, String productNo, String name, Long price,Long quantity) {
this.productId = productId;
this.productNo = productNo;
this.name = name;
this.price = price;
this.quantity = quantity;
}
public static ProductListResponseDto of(Product product, Long quantity) {
return ProductListResponseDto.builder()
.productId(product.getId())
.productNo(product.getProductNo())
.name(product.getName())
.price(product.getPrice())
.quantity(quantity)
.build();
}
public static ProductListResponseDto of(OrderDetail orderDetail) {
return ProductListResponseDto.builder()
.productId(orderDetail.getProduct().getId())
.productNo(orderDetail.getProduct().getProductNo())
.name(orderDetail.getProduct().getName())
.price(orderDetail.getProduct().getPrice())
.quantity(orderDetail.getQuantity())
.build();
}
}
현재 Product 엔티티의 Id는 @GeneratedValue(strategy = GenerationType.IDENTITY) 로 이루어져 있습니다.
추가적으로 @ActiveProfiles("test")에 해당하는 yml의 일부는 아래와 같습니다.
datasource:
url: jdbc:h2:mem:~/Marketbridge
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: none
show-sql: true
properties:
hibernate:
format_sql: true
default_batch_fetch_size: 100
defer-datasource-initialization: true
h2:
console:
enabled: true
이런 경우는 처음이라 어디가 잘못됐는지 찾지 못하겠네요 ㅠㅠ
답변 1
1
안녕하세요. 유선목님, 공식 서포터즈 y2gcoder입니다.
@GeneratedValue(strategy = GenerationType.IDENTITY)
를 통해 만드는 auto inrement 값은 트랜잭션 롤백의 영향을 받지 않습니다! 아래의 두 링크를 참고해주십쇼!
https://ymkmoon.github.io/Java-29-Jpa-Primary-Key/
감사합니다.
감사합니다!