MockMVC in Standalone Mode
컨트롤러 로직을 서버를 구동하지 않고 테스트하는 경우를 Inside-Servce Test라고 한다.
실제 컨트롤러에 Mock 객체를 주입해줘야 한다.
@Runwith(MockitoJUnitRunner.class)
public class ControllerMockMvcStandaloneTest {
private MockMvc mvc;
@Mock
private MockingRepository repository;
@InjectMokcs
private ControllerUnterTest controller;
}
Setup 메서드에서 MockMVC를 standalone 모드로 구성하여 HTTP Request를 실제로 보내는 것처럼 목 객체를 만들어야 한다.
Mockito Given()을 활용해 컨트롤러 내부에서 사용되는 Service, Repository 레이어에 대한 반환값을 미리 지정한다.
MockMVC With WebApplicationContext
이 방법에서는 1번 과정에서는 MockMVC만 사용했던 것과 달리 Spring의 WebApplicationContext를 로드해 빈을 주입해준다.
@Runwith(SpringRunner.class)
@WebMvcTest(ControllerUnterTest.class)
public class ControllerMockMvcStandaloneTest {
@Autowired
private MockMvc mvc;
@MockBean
private MockingRepository repository;
@InjectMokcs
private ControllerUnterTest controller;
}
SpringRunner과 실행되기 때문에 Context가 초기화되며 빈들이 로딩+주입된다.
@WebMVCTest 어노테이션을 사용해 MockMVC 인스턴스가 자동 설정된다. 이를 통해 MockMVC에 @Autowired 사용이 가능해진다.
@WebMvcTest
Spring MVC 컴포넌트에만 집중한 Spring MVC Test에 사용될 수 있다. 이 어노테이션은 스프링 컨텍스트 전체의 auto-configuration을 지원하지 않는다. @Controller, @ControllerAdvice 등과 같은 MVC 테스트에만 관련된 설정 정보만 가져온다.
기본적으로 이 어노테이션은 스프링 시큐리티와 MockMvc에 대한 auto-configure를 지원한다. 좀더 세밀한 제어를 위해선 @AutoConfigureMockMvc 주석을 사용할 수 있다.
일반적으로 이 어노테이션은 @MockBean, @Import와 사용된다. 그 이유는 앞서 말했듯 컨트롤러와 관련된 빈 설정 정보만 가져오기 때문에 컨트롤러에 필요한 빈들을 주입하기 위해서다. 따라서 만약 전체 애플리케이션에 대한 빈을 주입해줘야 한다면, 차라리 @AutoConfigurationMockMvc을 결합한 @SpringBootTest를 사용하는 것이 낫다.
JUnit4를 사용한다면 @RunWith(SpringRunner.class)와 같이 사용하면 된다.
다른 것들의 동작은 배재한, 컨트롤러 로직만을 위한 단위테스트는 항상 작성하려고 해야합니다.
→ 이때 첫번째 전략을 이용하세요 : use MockMVC in Standalone mode.
웹 계층과 관련된 주변 행동들을 테스트 해야한다면 ( 필터링, 인터셉터, 권한 등) 네번째 전략을 이용하세요 : SpringBootTest with a web server on a random port.