• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

@Transactional 어노테이션을 붙이지 않은 테스트가 통과하는 이유

23.12.30 23:02 작성 23.12.30 23:03 수정 조회수 170

0

1. 문제

HelloRepositoryTest 테스트 실행 시 findHelloFailed() 테스트 실패 및 에러 발생

Expected :null
Actual   :tobyspring.hello.Hello@579846cc

 

2. 강의 정보

  • 제목: [섹션 10] 스프링 부트의 자동 구성과 테스트로 전환

  • 시간: 6:23

  • 내용: HelloRepositoryTest.java의 @HellobootTest를 @SpringBootTest로 변경 후 실행

 

3. 내 프로젝트 상태

  • HelloRepositoryTest.java 코드

package tobyspring.hello;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class HelloRepositoryTest {

	@Autowired
	private HelloRepository helloRepository;

	@Test
	void findHelloFailed() {

		assertThat(helloRepository.findHello("Toby")).isNull();
	}

	@Test
	void increaseCount() {

		assertThat(helloRepository.countOf("Toby")).isEqualTo(0);

		helloRepository.increaseCount("Toby");
		assertThat(helloRepository.countOf("Toby")).isEqualTo(1);

		helloRepository.increaseCount("Toby");
		assertThat(helloRepository.countOf("Toby")).isEqualTo(2);
	}
}

 

4. 해결 과정

  • increaseCount() 테스트 실행 결과가 findHelloFailed() 테스트에 영향을 미치는 것으로 추정

  • 따라서 @Transaction을 @SpringBootTest 아래 줄에 추가

package tobyspring.hello;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@Transactional
public class HelloRepositoryTest {

	@Autowired
	private HelloRepository helloRepository;

	@Test
	void findHelloFailed() {

		assertThat(helloRepository.findHello("Toby")).isNull();
	}

	@Test
	void increaseCount() {

		assertThat(helloRepository.countOf("Toby")).isEqualTo(0);

		helloRepository.increaseCount("Toby");
		assertThat(helloRepository.countOf("Toby")).isEqualTo(1);

		helloRepository.increaseCount("Toby");
		assertThat(helloRepository.countOf("Toby")).isEqualTo(2);
	}
}

 

5. 결과

정상적으로 테스트 통과

 

6. 질문

강의에서 @Transactional 어노테이션 없이 테스트를 통과할 수 있었던 이유가 궁금합니다!

 

답변 2

·

답변을 작성해보세요.

1

날카로운, 좋은 질문을 해주셨네요. 🙂

이번 강의에선 테스트에 관해서는 깊이 들어가지 않으려고 했습니다. 그래서 말씀하신 트랜잭션, 테스트 중 DB 변경 등에 대해서 따로 언급하지는 않았네요.

강의에서 사용한 프로젝트에서는 환경설정 등에 따로 신경쓰지 않도록 간단히 인메모리 DB를 사용했습니다. 이 경우 DB 기능이 동작은 하는데 메모리에만 기록하기 때문에 애플리케이션이 종료되면 메모리에 써진 정보가 다 날라가서 DB가 초기화 됩니다. 그래서 위와 같은 테스트를 여러번 실행해도 매번 새 DB를 설치하고 사용하는 것과 동일한 효과가 생기는 것이죠. 그래서 굳이 @Transactional을 넣지 않았습니다. 만약 MySQL과 같은 DB를 연결했다면 말씀하신대로 테스트에서 추가, 변경한 정보가 다른 테스트 또는 다음 테스트에 영향을 주지 않도록 @Transactional을 붙인 롤백 테스트를 만들거나, 테스트 후에 DB 정보를 초기화하는 코드가 필요하겠네요.

아래 AI 인턴이 찾아준 질문은 강의 내용과 직접 관련은 없지만 @Transactional을 붙인 스프링의 롤백 테스트와 관련한 논쟁에 대해 여러가지 설명이 있습니다. 관심 있으면 살펴보세요.

jiun koo님의 프로필

jiun koo

질문자

2023.12.31

넵 말씀 감사합니다!

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.12.30

안녕하세요, 인프런 AI 인턴입니다.

해당 강의 ‘토비의 스프링 부트 - 이해와 원리’에서의 @Transactional 어노테이션을 붙이지 않았을 때 테스트가 통과하는 이유에 대한 궁금증을 해결해 드리고자 합니다. 이와 유사한 경우로, 강의 수강생이 @Transactional 어노테이션 관련하여 질문하였고, 토비 선생님이 직접 답변한 내용이 있습니다. 아래의 URL을 통해 유사한 상황에 대한 선생님의 답변을 확인해 보시면 도움이 될 것 같습니다.

또한 @Transactional 어노테이션의 역할과 테스트에서의 중요성에 대해서도 설명이 되어 있으니 참고하시면 좋을 것 같습니다.
다른 궁금한 점이 있으시면 언제든지 질문해 주세요.