inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 데이터 JPA

테스트에 @Transactional 추가해도 안되네요..

621

taehee-kim-dev

작성한 질문수 21

0

기선님 안녕하세요!

저번에 JPA 테스트에서, 같은 객체에 대해서 assertThat을 두 번 했었습니다.

저는 JPA가 select문을 한 번만 날리고 그 객체로 assertThat을 두 번 할거라 예상했지만,

예상과 다르게 JPA는 select문을 각 asserThat문 마다 한 번씩, 총 두 번 날렸습니다.

그래서 제가 질문을 올렸었습니다. 왜 select문이 한 번만 날아가지 않고 두 번 다 날아가는지 모르겠다구요..

기선님이 @Transactional 을 테스트에 붙여보라고 하셨습니다.

사실 그때도 service 클래스에 @Transactional이 붙어있긴 했습니다.

기선님이 말씀하신 대로 테스트에 @Transactional을 붙여서 했는데 해결이 되지않아 다시 질문드립니다!!

일단 서비스 클래스입니다. 원래 @Transactional 어노테이션은 붙어있었습니다.

기선님이 말씀하신대로 테스트에 @Transactional 추가했습니다.

먼저 save 후 확인하는 테스트 코드입니다.

테스트 결과입니다. 테스트는 성공했습니다. 하지만 전과 같이 select문이 두 번 날아갔습니다.

그리고 왜인지는 모르겠는데 전에는 롤백이 없었는데,

test함수에 @Transactional을 추가하니 롤백이 생겼습니다ㅠ

save 후 update하여 확인하는 테스트 코드입니다.

에러가 났습니다..

insert후 select했는데 왜 났는지 모르겠네요 ㅠ

그 밑에 select문을 두 번 날리는 것은 같더군요..

왜 select를 한번만 하지 않는지, save 테스트에서 롤백은 왜 하는지, update테스트는 왜 에러가 나는지 모르겠습니다..ㅠ

spring JPA java

답변 7

0

백기선

더 이상은 좀 더 학습을 하신 다음에 한달 뒤 쯤 그래도 모르시겠으면 알려드리겠습니다.

0

taehee-kim-dev

아... 정말 감사합니다!! 그걸 생각 못했네요 ㅠ

근데 궁금한게 더 있는데요,

Q1. Service 클래스에 @Transactional 붙였으면 테스트에선 안붙여도 테스트 할 때 트랜잭션 처리 하는거죠?

Q2. 위에 마지막 깨진 테스트요.. 성공했을 때와 실패했을 때의 차이점은 테스트에 @Transactional을 추가로 붙인건데 왜 깨졌을까요??

자세한 답변 정말 감사드립니다!!

0

백기선

코드를 봤는데 select는 findAll 할때 한번 발생했고 그 다음에 오는 select는 deleteAll() 때문에 발생한거네요.

@After
public void cleanUp(){
postRepository.deleteAll();
}

deleteAll() 구현체가 기존 데이터를 가져와서 전부 delete(E entity) 를 호출해주기 때문입니다.

0

taehee-kim-dev

제가 random_port설정으로 했는데 이게 관련있나요??

0

taehee-kim-dev

https://github.com/taehee-kim-dev/mysecretconcerns-webservice

해당 코드 전체 프로젝트입니다!!

직접 테스트도 해주시고 자세한 설명 정말 감사합니다 ㅠ

0

백기선

제 환경에서 비슷하게 작성해서 테스트를 해봤으나. 재현이 되지 않습니다.

@Transactional
@SpringBootTest
class BookRepositoryTest {

@Autowired BookRepository bookRepository;

@Test
void test() {
Book book = new Book();
book.setTitle("spring");
bookRepository.save(book);

List<Book> all = bookRepository.findAll();

assertEquals("spring", all.get(0).getTitle());
assertEquals("spring", all.get(0).getTitle());
}

} 

Select 쿼리가 하나만 발생합니다.

@Transactional 애노테이션을 추가했을 때 롤백이 발생하는건 스프링 테스트가 제공하는 기능입니다. 테스트에 사용한 트랜잭션은 기본을 롤백으로 처리해서 다른 테스트에 영향을 주지 않기 위한 기능입니다. 자세한 내용은 스프링 레퍼런스를 참고하세요.

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html#testing-introduction

그리고 수정하는 테스트가 깨진 이유는 코드를 보지 않고서는 저도 잘 모르겠습니다.

0

백기선

일단 코드를 깃헙에 올려서 공유해 주시면 좋겠네요.

spring boot 2.7.13-SNAPSHOT trace 소문자 로그 안나옴

0

533

1

<스프링 데이터 Common: 기본 리포지토리 커스터마이징> 에 대한 질문

0

392

1

comment table에서 저장될떄 왜 id값이 2부터저장이되는건가요?

0

407

1

@EnableJpaRepositories 설정을 스프링부트가 어디에서 자동설정하나요?

0

451

0

PersistenceContext 관련 질문드립니다.

0

335

1

지금(Eager), 나중에(Lazy)의 의미를 모르겠습니다

0

338

1

transaction 구간이 길어질 경우의 처리방법 문의드립니다.

0

905

1

docker postgres

0

293

1

Multiple DataSource 사용 시 transaction 관련 질문 드립니다.

0

2908

1

entity 중 null이 아닌 필드만 update 할 방법이 있을까요?

0

1190

1

Eager 모드일 경우, join을 inner join으로 바꾸는 법이 있을까요?

0

385

1

엔티티를 상속받는 DTO가 일반적인가요?

1

1847

1

커스텀 타입 클래스를 String 타입 처럼 이용해 쿼리하는 방법에 대해 질문하고 싶습니다.

0

339

1

연관관계 매핑 어떤식으로 해야될지 감이 안잡힙니다.

0

566

4

EntityManager 주입시 Annotation관련 질문드립니다.

0

565

1

클래스 기반 프로젝션 사용 관련 질문

0

560

1

save 메서드 질문드립니다.

0

258

1

복잡한 통계쿼리도 JPA로 가능한가요?

2

5593

1

find 와 get의 차이가 무엇인가요?

0

890

1

실무에서 JPA 할 때 FK로 개발할때 연관관계를 꼭 맺어주어야 하나요?

0

998

1

\dt Did not find any relations.

0

481

1

소스코드는 어디서 볼 수 있을까요?

1

287

1

table 생성과 select 문에 대한 질문

0

174

1

스프링 데이터 RepositoryTest 관련 질문

0

2173

2