Spring Security 를 사용 중이라면 가짜 시큐리티를 만들어줘야 합니다.
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();
}
}
통합 테스트:
// Controller 를 테스트 하기 위한 설정. @WebMvcTest.
@WebMvcTest(
controllers = {UserController.class, ProductController.class},
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = WebSecurityConfig.class
)
}
)
class UserProductMvcTest {
private MockMvc mvc; // http 요청을 가짜로 날릴 수 있음.
private Principal mockPrincipal;
@Autowired
private WebApplicationContext context;
@Autowired
private ObjectMapper objectMapper;
@MockBean
UserService userService;
@MockBean
FolderService folderService;
// @MockBean
// KakaoService kakaoService;
@MockBean
ProductService productService;
@BeforeEach
public void setup() {
mvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity(new MockSpringSecurityFilter())) // Security를 사용하니까 가짜 Security를 만들어야함
.build();
}
private void mockUserSetup() {
// Mock 테스트 유져 생성
String username = "sollertia4351";
String password = "robbie1234";
String email = "sollertia@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("로그인 Page")
void test1() throws Exception {
// when - then
mvc.perform(get("/api/user/login-page"))
.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", "sollertia4351");
signupRequestForm.add("password", "robbie1234");
signupRequestForm.add("email", "sollertia@sparta.com");
signupRequestForm.add("admin", "false");
// when - then
mvc.perform(post("/api/user/signup")
.params(signupRequestForm)
)
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/api/user/login-page"))
.andDo(print());
}
@Test
@DisplayName("신규 관심상품 등록")
void test3() throws Exception {
// given
this.mockUserSetup();
String title = "Apple <b>아이폰</b> 14 프로 256GB [자급제]";
String imageUrl = "https://shopping-phinf.pstatic.net/main_3456175/34561756621.20220929142551.jpg";
String linkUrl = "https://search.shopping.naver.com/gate.nhn?id=34561756621";
int lPrice = 959000;
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());
}
}
@WebMvcTest 를 설정하여 Controller를 테스트 할 수 있습니다. 이때 테스트할 컨트롤러와 제외할 필터를 명시합니다.
@WebMvcTest(
controllers = {UserController.class, ProductController.class},
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = WebSecurityConfig.class
)
}
)
MockMvc 객체-mvc를 만들어 테스트를 위한 http 요청을 실행할 수 있습니다.
mvc에 WebApplicationContext를 설치하고 가짜 SpringSecurity를 적용합니다.
@BeforeEach
public void setup() {
mvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity(new MockSpringSecurityFilter())) // Security를 사용하니까 가짜 Security를 만들어야함
.build();
}
아래와 같은 식으로 mvc를 구성하며, 요청에 대한 정보와 예측값 등을 넣어줍니다.
mvc.perform(get("/api/user/login-page"))
.andExpect(status().isOk())
.andExpect(view().name("login"))
.andDo(print());
mvc.perform(post("/api/user/signup")
.params(signupRequestForm)
)
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/api/user/login-page"))
.andDo(print());
mvc.perform(post("/api/products")
.content(postInfo)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.principal(mockPrincipal)
)
.andExpect(status().isOk())
.andDo(print());
'Spring' 카테고리의 다른 글
45. 통합 테스트 (0) | 2024.12.06 |
---|