스프링 MVC 테스트

송영재·2022년 10월 30일

Spring

목록 보기
27/45
  • 24) 스프링 MVC 테스트
    • [코드스니펫] build.gradle

      testImplementation 'org.springframework.security:spring-security-test'
    • [코드스니펫] test > mvc > MockSpringSecurityFilter

      import org.springframework.security.core.Authentication;
      import org.springframework.security.core.context.SecurityContextHolder;
      
      import javax.servlet.*;
      import javax.servlet.http.HttpServletRequest;
      import java.io.IOException;
      
      public class MockSpringSecurityFilter implements Filter {
          @Override
          public void init(FilterConfig filterConfig) {}
      
          @Override
          public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
              SecurityContextHolder.getContext()
                      .setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
              chain.doFilter(req, res);
          }
      
          @Override
          public void destroy() {
              SecurityContextHolder.clearContext();
          }
      }
    • [코드스니펫] test > mvc > UserProductMvcTest

      ```java
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.sparta.springcore.controller.ProductController;
      import com.sparta.springcore.controller.UserController;
      import com.sparta.springcore.dto.ProductRequestDto;
      import com.sparta.springcore.model.User;
      import com.sparta.springcore.model.UserRoleEnum;
      import com.sparta.springcore.security.UserDetailsImpl;
      import com.sparta.springcore.security.WebSecurityConfig;
      import org.junit.jupiter.api.BeforeEach;
      import org.junit.jupiter.api.DisplayName;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
      import org.springframework.boot.test.mock.mockito.MockBean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.FilterType;
      import org.springframework.http.MediaType;
      import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
      import org.springframework.test.web.servlet.MockMvc;
      import org.springframework.test.web.servlet.setup.MockMvcBuilders;
      import org.springframework.util.LinkedMultiValueMap;
      import org.springframework.util.MultiValueMap;
      import org.springframework.web.context.WebApplicationContext;
      
      import java.security.Principal;
      
      import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
      import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
      import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
      import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
      import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
      import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
      
      @WebMvcTest(
              controllers = {UserController.class, ProductController.class},
              excludeFilters = {
                      @ComponentScan.Filter(
                              type = FilterType.ASSIGNABLE_TYPE,
                              classes = WebSecurityConfig.class
                      )
              }
      )
      class UserProductMvcTest {
          private MockMvc mvc;
      
          private Principal mockPrincipal;
      
          @Autowired
          private WebApplicationContext context;
      
          @Autowired
          private ObjectMapper objectMapper;
      
          @MockBean
          UserService userService;
      
          @MockBean
          KakaoUserService kakaoUserService;
      
          @MockBean
          ProductService productService;
      
          @BeforeEach
          public void setup() {
              mvc = MockMvcBuilders.webAppContextSetup(context)
                      .apply(springSecurity(new MockSpringSecurityFilter()))
                      .build();
          }
      
          private void mockUserSetup() {
              // Mock 테스트 유져 생성
              String username = "제이홉";
              String password = "hope!@#";
              String email = "hope@sparta.com";
              UserRoleEnum role = UserRoleEnum.USER;
              User testUser = new User(username, password, email, role);
              UserDetailsImpl testUserDetails = new UserDetailsImpl(testUser);
              mockPrincipal = new UsernamePasswordAuthenticationToken(testUserDetails, "", testUserDetails.getAuthorities());
          }
      
          @Test
          @DisplayName("로그인 view")
          void test1() throws Exception {
              // when - then
              mvc.perform(get("/user/login"))
                      .andExpect(status().isOk())
                      .andExpect(view().name("login"))
                      .andDo(print());
          }
      
          @Test
          @DisplayName("회원 가입 요청 처리")
          void test2() throws Exception {
              // given
              MultiValueMap<String, String> signupRequestForm = new LinkedMultiValueMap<>();
              signupRequestForm.add("username", "제이홉");
              signupRequestForm.add("password", "hope!@#");
              signupRequestForm.add("email", "hope@sparta.com");
              signupRequestForm.add("admin", "false");
      
              // when - then
              mvc.perform(post("/user/signup")
                              .params(signupRequestForm)
                      )
                      .andExpect(status().is3xxRedirection())
                      .andExpect(view().name("redirect:/user/login"))
                      .andDo(print());
          }
      
          @Test
          @DisplayName("신규 관심상품 등록")
          void test3() throws Exception {
              // given
              this.mockUserSetup();
              String title = "Apple <b>에어팟</b> 2세대 유선충전 모델 (MV7N2KH/A)";
              String imageUrl = "https://shopping-phinf.pstatic.net/main_1862208/18622086330.20200831140839.jpg";
              String linkUrl = "https://search.shopping.naver.com/gate.nhn?id=18622086330";
              int lPrice = 77000;
              ProductRequestDto requestDto = new ProductRequestDto(
                      title,
                      imageUrl,
                      linkUrl,
                      lPrice
              );
      
              String postInfo = objectMapper.writeValueAsString(requestDto);
      
              // when - then
              mvc.perform(post("/api/products")
                              .content(postInfo)
                              .contentType(MediaType.APPLICATION_JSON)
                              .accept(MediaType.APPLICATION_JSON)
                              .principal(mockPrincipal)
                      )
                      .andExpect(status().isOk())
                      .andDo(print());
          }
      }
      ```

      🌐 그 외 다양한 Spring Boot 테스트 Annotation
      https://www.baeldung.com/spring-boot-testing

0개의 댓글