MockMvc
실제로 네트워크에 연결하지 않고도 API 테스트가 가능하도록 모킹된 객체이다.
MockMvcBuiler를 사용해서 파라미터를 반드시 셋팅해주어야 하는데 webAppContextSetup
혹은 standaloneSetup
중 하나만 셋해주면 된다.
좌측은 webAppContextSetup
를 설정한 경우이고, 우측은 standaloneSetup
를 설정한 경우이다.
webAppContextSetup를 설정하기 위해선 자동 주입된 WebApplicationContext객체를 사용해야하는데, 이를 실행해보면 빈으로 등록할 수 없다고 뜬다. 사실 원인을 잘 모르겠어서 우측으로 만들어 두기는 했는데 큰 차이는 없어보인다. 만약에 MockMvc를 테스트 하는 파일이 많아져 해당 설정을 추상 클래스로 분리하고자 할 때 문제가 생길 듯🤔..
@WebAppConfiguration
을 테스트 클래스에 추가하면 문제없이 실행된다!
webAppContextSetup(WebApplicationContext context)
Build a MockMvc instance using the given, fully initialized (i.e., refreshed) WebApplicationContext.
파라미터로 주어진 초기화된 WebApplicationContext를 사용하여 MockMvc 인스턴스를 작성한다.
standaloneSetup(Object... controllers)
Build a MockMvc instance by registering one or more @Controller instances and configuring Spring MVC infrastructure programmatically.
@Controller 인스턴스를 하나 이상 등록하고 Spring MVC 인프라를 프로그래밍 방식으로 구성하여 MockMvc 인스턴스를 만든다.
ref. Spring Mvc Test Api
"webAppContextSetup"은 실제 Spring MVC 구성을 로드하여 보다 완벽한 통합 테스트를 수행한다. TestContext 프레임워크는 로드된 Spring 구성을 캐시하므로, 더 많은 테스트가 추가되더라도 테스트를 빠르게 실행하도록 돕는다. 또한 웹 계층 테스트에 계속 집중하기 위해 Spring 구성을 통해 컨트롤러에 Mock 서비스를 주입할 수 있다.
반면에 "standaloneSetup"은 단위 테스트에 약간 더 가깝다. 한 번에 하나의 컨트롤러를 테스트하고, 컨트롤러에 수동으로 모의 종속성을 주입할 수 있으며, 스프링 구성을 로드하는 것도 포함되지 않는다. 이러한 테스트는 스타일에 더 중점을 두고 어떤 컨트롤러가 테스트되고 있는지, 특정 스프링 MVC 구성이 작동해야하는지 등을 쉽게 볼 수 있습니다. "standaloneSetup"은 또한 어떤 행동을 확인하거나 문제를 디버깅하기 위해 애드혹 테스트를 작성하는 매우 편리한 방법이다.
통합 대 단위 테스트와 마찬가지로 옳고 그른 대답은 없다. "standaloneSetup"을 사용하면 스프링 MVC 구성을 검증하기 위해 추가 "webAppContextSetup"테스트가 필요하다.
혹은 "webAppContextSetup"으로 모든 테스트를 작성하고 항상 실제 스프링 MVC 구성에 대해 테스트할 수도 있다.
ref. stackoverflow - Are Spring's MockMvc used for unit testing or integration testing?
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/applicationContext.xml", "file:src/main/webapp/WEB-INF/dispatcher-servlet.xml"})
@Transactional
@WebAppConfiguration
public class BoardApiControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mvc;
@BeforeEach
public void initMvc() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
.....
}
기본 경로로 web.xml에 지정된 applicationContext
에서 정보를 가져와서 WebApplicationContext을 구축해주는 듯!!