목차
@WebMvcTest
Spring MVC 를 테스트하기 위해 사용되는 어노테이션, MVC 테스트와 관련된 Configuration 이 적용된다.
- @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, HandlerMethodArgumentResolver, WebMvcConfigurer 를 Scan 한다.
- @Component, @Service, @Repository Bean은 적용되지 않는다.
- MVC 테스트시 Spring Security 설정도 자동적으로 추가해준다.
- controllers 속성을 이용해 특정 Controller 를 지정함으로써 해당 Controller 만 테스트 진행할 수 있다.
- includeFilters 속성과 excludeFilters 속성을 이용해 특정 Filter 를 추가하거나 제외할 수 있다.
장점
- @SpringBootTest 에 비해 MVC 에 필요한 구성만 불러옴으로 훨씬 가볍고 빠르다.
단점
- Mock 기반 테스트를 진행하기 때문에 운영에서는 제대로 동작하지 않을 수 있다.
@WebMvcTest 를 이용한 Test 코드
@WebMvcTest( value = PostController.class , excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JsonSecurityConfig.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JwtSecurityConfig.class)} ) @ActiveProfiles("local") class PostControllerTest {
@MockBean private JwtUtils jwtUtils;
@Autowired private MockMvc mockMvc;
@MockBean private PostService postService;
@MockBean private CategoryService categoryService;
@Autowired private ObjectMapper objectMapper;
@MockBean(name = "userDetailsService") private UserInfoUserDetailsService userInfoUserDetailsService;
@PostConstruct public void setup() { given(userInfoUserDetailsService.loadUserByUsername(anyString())) .willReturn(new User("test", "password", AuthorityUtils.createAuthorityList("ROLE_WRITE"))); }
@Test @WithMockUser void getAllTest() throws Exception { List<Page> posts = new ArrayList<>(); given(postService.getAllPosts(PageRequest.of(0, 3))).willReturn(new PageImpl(posts));
ResultActions resultActions = mockMvc.perform(get("/api/post"));
resultActions .andExpect(status().isOk()); }
@Test @WithUserDetails void saveTest() throws Exception { String title = new String("Title"); String subTitle = new String("subTitle"); String content = new String("content"); String beforeCategoryName = new String("beforeCategory"); String afterCategoryName = new String("afterCategory");
RequestPostDto requestPostDto = new RequestPostDto(); requestPostDto.setTitle(title); requestPostDto.setSubTitle(subTitle); requestPostDto.setContent(content); requestPostDto.setCategory(afterCategoryName);
Category beforeCategory = Category.builder() .name(beforeCategoryName) .posts(new ArrayList<>()) .build();
Category afterCategory = Category.builder() .name(afterCategoryName) .posts(new ArrayList<>()) .build();
Post post = Post.builder() .id(1L) .title(title) .subTitle(subTitle) .content(content) .category(beforeCategory) .build();
given(categoryService.saveOrFindCategory(afterCategoryName)).willReturn(afterCategory); given(postService.savePost(any(Post.class))).willReturn(post);
String requestBody = objectMapper.writeValueAsString(requestPostDto);
ResultActions resultActions = mockMvc.perform(post("/api/post/new") .with(csrf()) .content(requestBody) .contentType(MediaType.APPLICATION_JSON) );
resultActions .andExpect(status().isCreated()) .andDo(print());
verify(postService).savePost(any(Post.class)); }
@Test @WithUserDetails void saveFailTest() throws Exception { String title = new String("Title"); String subTitle = new String("subTitle"); String content = new String("content"); String afterCategoryName = new String("afterCategory");
RequestPostDto requestPostDto = new RequestPostDto(); requestPostDto.setTitle(title); requestPostDto.setSubTitle(subTitle); requestPostDto.setContent(content); requestPostDto.setCategory(afterCategoryName);
Category afterCategory = Category.builder() .name(afterCategoryName) .posts(new ArrayList<>()) .build();
given(categoryService.saveOrFindCategory(afterCategoryName)).willReturn(afterCategory); given(postService.savePost(any(Post.class))).willThrow(PostSaveFailException.class);
String requestBody = objectMapper.writeValueAsString(requestPostDto);
ResultActions resultActions = mockMvc.perform(post("/api/post/new") .content(requestBody) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) );
resultActions .andExpect(status().isBadRequest()) .andDo(print());
verify(postService).savePost(any(Post.class)); }
@Test @WithUserDetails void deletePostTest() throws Exception { Long id = 1L;
ResultActions resultActions = mockMvc.perform(delete("/api/post/delete/" + id) .with(csrf()));
resultActions .andExpect(status().isOk()) .andDo(print());
verify(postService).deletePost(1L); } }
|