Spring 테스트를 위한 어노테이션들

ParkIsComing·2024년 5월 19일

Spring

목록 보기
20/21

@WebMvcTest

  • 보통 컨트롤러만 테스트하고 싶을 때 사용한다.
  • Web Layer 관련 빈들만 등록한다.
    • ⇒ Security, Filter, Interceptor, request/response Handling, Controller를 스캔 대상으로 한다.
    • @Repository@Service는 등록하지 않는다. 사용할 것이라면 @MockBean을 사용해서 등록해줘야
  • 서블릿 컨테이너를 모킹한 MovkMVC 타입의 객체를 mock up하여 컨트롤러에 대한 테스트 코드를 작성한다.
  • @SpringBootTest를 사용한 테스트보다는 가볍다.

MockMVC

  • 웹 앱을 애플리케이션 서버에 배포하지 않고도 테스트를 위한 요청을 제공하는 유틸리티 클래스이다. GET, POST< PATCH, DELETE 등의 요청을 생성해 보낼 수 있다.
  • 비슷하게 WebTestClient와 TestRestTemplate도 API 테스트를 위해 사용할 수 있지만, 이들은 실제 서버를 구동시킨다는 점에서 다르다.

@ AutoConfigureMockMvc와의 비교

  • @AutoConfigureMockMvc를 사용하면 @WebMvcTest 없이도 MockMvc를 사용할 수 있다.
  • @SpringBootTest와 함께 사용된다.
  • @WebMvcTest와 다른 점은 Web Layer 관련 빈외에 @Service@Repository가 붙은 빈들도 스캔된다는 것이다.

예시를 통해 사용 방법을 알아보자.

@WebMvcTest(GreetingController.class)
class WebMockTest {

	@Autowired
	private MockMvc mockMvc;

	@MockBean
	private GreetingService service;

	@Test
	void greetingShouldReturnMessageFromService() throws Exception {
		when(service.greet()).thenReturn("Hello, Mock");
		this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
				.andExpect(content().string(containsString("Hello, Mock")));
	}
}

GreetingController 클래스에 대한 테스트를 실행하는 코드이다.

  • MockMvc 객체를 주입 받아 실제 서버의 구동 없이 테스트할 수 있다.
  • @MockBean을 사용해 GreetingService를 Mock으로 주입받아 사용한다. 이를 통해 서비스단에 대한 의존성 없이 컨트롤러에 대한 단위테스트가 가능해진다.
  • /greeting 엔드포인트 GET 요청을 받아 응답 상태가 200 OK인지, 응답 내용에 특정 문자열이 포함되어 있는지 확인한다.

@SpringBootTest

  • 실제 구동되는 애플리케이션과 동일하게 전체 컨텍스트를 로드하여 빈을 주입하기 때문에 속도가 느리고, 통합 테스트를 할 때 많이 사용한다.
  • 빈을 주입받아 테스트하기 때문에, 데이터가 삽입 또는 삭제되면 실제 데이터에 변화가 생길 수 있다. 따라서 @Tractional 어노테이션을 사용해 테스트 이후 rollback하도록 해야 한다.
  • 프로젝트의 컨트롤러, 리포지토리, 서비스가 @Autowired로 다 주입된다.
  • 자동으로 Mock을 빈으로 등록하지 않는다.
    • @SpringBootTest에서 MockMvc 객체를 사용하려면, @AutoConfigureMockMvc 어노테이션을 함께 선언해줘야
  • @ExtendWith(SpringExtension.class)를 포함한다. (Junit5 기준)

예시를 통해 살펴보자.

@SpringBootTest
@AutoConfigureMockMvc
class TestingWebApplicationTest {

	@Autowired
	private MockMvc mockMvc;

	@Test
	void shouldReturnDefaultMessage() throws Exception {
		this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
				.andExpect(content().string(containsString("Hello, World")));
	}
}
  • MockMVC 객체를 주입받아 실제 웹 서버를 구동하지 않고도 컨트롤러를 테스트한다.
  • GET 요청에 대해서 응답 상태가 200 OK인지 확인하고, 응답 본문에 특정 문자열이 포함하는지 검증함으로써 애플리케이션이 제대로 동작하는지 확인한다.

@DataJpaTest

Spring Data JPA 테스트를 위한 슬라이스 테스트 어노테이션이다.

  • 기본적으로 H2와 같은 메모리 기반의 내장 DB를 사용해 테스트한다.달리 말하면 실제 데이터베이스를 사용하지 않고 간단하게 테스트가 가능한 것이다. 하지만 필요에 따라 MySQL 같은 DB를 연동해서도 사용 가능하다.
  • @Entity가 선언된 클래스를 스캔하여 repository를 구성한다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(DataJpaTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoConfigureDataJpa
@AutoConfigureTestDatabase// -> this annotation!
@AutoConfigureTestEntityManager
@ImportAutoConfiguration
public @interface DataJpaTest {

}
  • @AutoConfigureTestDatabase
    • 사용시에 replace, connection 등의 조건을 설정할 수 있다.
    • connection :
      @AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2) 와 같이 설정하면 H2를 테스트 DB로 사용할 수 있다.
    • replace :
      @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 와 같은 설정을 주면 내장된 메모리 DB로 변경하지 못하도록 막는다. (테스트 DB가 아닌 기존 DB를 사용하는 것이다.))
  • @Transactional
    • 테스트가 완료되면 자동으로 롤백 될 수 있게 한다.

이처럼 통합 테스트인지 단위테스트인지, 테스트하고자 하는 기능이 무엇인지에 따라 테스트를 위한 다양한 어노테이션을 사용할 수 있다.

0개의 댓글