MockMvc는 perform()을 통해 httpRequest를 내가 짠 메서드에 맞게 세팅한 후 andExpect()를 통해 그 결과를 확인할 수 있음
현재 상태에서는 처리 상태에 따라 view가 제대로 리턴이 되는지, status 값이 원하는대로 리턴되는지 확인하고 있음
@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("/members")
public class MemberController {
private final MemberService memberService;
private final MessageSource ms;
/**
* 등록 실행
* @param profileFile
* @param registerForm
* @param bindingResult
* @return
*/
@PostMapping("/register")
public String register(@RequestParam MultipartFile profileFile,
@Validated @ModelAttribute MemberRegisterForm registerForm, BindingResult bindingResult) {
if(memberService.isExistedMember(registerForm.getId())){
bindingResult.reject("existedMember");
} else if(!registerForm.getPassword().equals(registerForm.getPasswordCheck())){
bindingResult.reject("passwordMismatch");
}
if (bindingResult.hasErrors()) {
return "members/register";
}
try {
memberService.register(registerForm, profileFile);
} catch (EncryptAlgorithmFailException e) {
log.info("password encrypt fail, userId ={}", registerForm.getId());
throw new MemberException(ms.getMessage("failToRegist", null, null), e);
} catch (IOException e) {
log.info("profile file upload fail, userId ={}", registerForm.getId());
throw new MemberException(ms.getMessage("failToRegist", null, null), e);
}
return "redirect:/members/successedRegister";
...
}
@ExtendWith(MockitoExtension.class)
class MemberControllerTest {
@InjectMocks
private MemberController memberController;
@Mock
private MemberService memberService;
private MockMvc mockMvc;
@BeforeEach
public void init() {
mockMvc = MockMvcBuilders.standaloneSetup(memberController).build();
}
@Test
public void 회원가입_유효성_검증_실패() throws Exception{
//given
MultiValueMap<String, String> memberRegisterInfo = new LinkedMultiValueMap<>();
memberRegisterInfo.add("id", "");
memberRegisterInfo.add("password", "");
memberRegisterInfo.add("passwordCheck", "");
memberRegisterInfo.add("nickname", "");
MockMultipartFile profileFile = new MockMultipartFile("file"
, "test.png"
, "img/png"
, new FileInputStream("/Users/choidayoung/dev/file/before/test.png"));
doReturn(false).when(memberService).isExistedMember(anyString());
//when
ResultActions result = mockMvc.perform(multipart("/members/register")
.file("profileFile", profileFile.getBytes())
.params(memberRegisterInfo)
.contentType(MediaType.APPLICATION_FORM_URLENCODED))
.andDo(print());
//then
result.andExpect(status().isOk())
.andExpect(view().name("members/register"));
}
@Test
public void 회원가입_존재하는_회원_실패() throws Exception{
//given
MultiValueMap<String, String> memberRegisterInfo = new LinkedMultiValueMap<>();
memberRegisterInfo.add("id", "choi1234@gmail.com");
memberRegisterInfo.add("password", "1234");
memberRegisterInfo.add("passwordCheck", "1234");
memberRegisterInfo.add("nickname", "maxx");
MockMultipartFile profileFile = new MockMultipartFile("file"
, "test.png"
, "img/png"
, new FileInputStream("/Users/choidayoung/dev/file/before/test.png"));
doReturn(true).when(memberService).isExistedMember(anyString());
//when
ResultActions result = mockMvc.perform(multipart("/members/register")
.file("profileFile", profileFile.getBytes())
.params(memberRegisterInfo)
.contentType(MediaType.APPLICATION_FORM_URLENCODED))
.andDo(print());
//then
result.andExpect(status().isOk())
.andExpect(view().name("members/register"));
}
@Test
public void 회원가입_비밀번호_확인_틀림_실패() throws Exception{
//given
MultiValueMap<String, String> memberRegisterInfo = new LinkedMultiValueMap<>();
memberRegisterInfo.add("id", "choi1234@gmail.com");
memberRegisterInfo.add("password", "1234");
memberRegisterInfo.add("passwordCheck", "1234456789");
memberRegisterInfo.add("nickname", "maxx");
MockMultipartFile profileFile = new MockMultipartFile("file"
, "test.png"
, "img/png"
, new FileInputStream("/Users/choidayoung/dev/file/before/test.png"));
doReturn(false).when(memberService).isExistedMember(anyString());
//when
ResultActions result = mockMvc.perform(multipart("/members/register")
.file("profileFile", profileFile.getBytes())
.params(memberRegisterInfo)
.contentType(MediaType.APPLICATION_FORM_URLENCODED))
.andDo(print());
//then
result.andExpect(status().isOk())
.andExpect(view().name("members/register"));
}
@Test
public void 회원가입_성공() throws Exception{
//given
MultiValueMap<String, String> memberRegisterInfo = new LinkedMultiValueMap<>();
memberRegisterInfo.add("id", "choi1234@gmail.com");
memberRegisterInfo.add("password", "1234");
memberRegisterInfo.add("passwordCheck", "1234");
memberRegisterInfo.add("nickname", "maxx");
MockMultipartFile profileFile = new MockMultipartFile("file"
, "test.png"
, "img/png"
, new FileInputStream("/Users/choidayoung/dev/file/before/test.png"));
doReturn(false).when(memberService).isExistedMember(anyString());
doReturn(new Member("M123456789","choi1234@gmail.com", "maxx","1234"))
.when(memberService).register(any(MemberRegisterForm.class), any(MultipartFile.class));
//when
ResultActions result = mockMvc.perform(multipart("/members/register")
.file("profileFile", profileFile.getBytes())
.params(memberRegisterInfo)
.contentType(MediaType.APPLICATION_FORM_URLENCODED))
.andDo(print());
//then
result.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/members/successedRegister"));
...
}
HttpRequest가 필요한 Controller에서는 MockMvc를 통해 Controller를 테스트할 수 있음
private MockMvc mockMvc;
@BeforeEach
public void init() {
mockMvc = MockMvcBuilders.standaloneSetup(memberController).build();
}