본문 바로가기
개발공부 개발새발/JAVA

Junit5 Test ) Controller 를 테스트 해보자!

by 휴일이 2023. 7. 1.

이번엔 Controller 를 테스트 해보겠다

Controller 는 HttpServletRequest 도 사용하고

값도 원래는 프론트에서 넣어줘야하는데

어떻게~~~할까용?

 

 

<MemberInfoController 의 "pwdUpdate" 메서드의 실패 케이스를 테스트해볼 것이다>

 

 

 

@SpringBootTest
@AutoConfigureMockMvc
class MemberInfoControllerTest {

    @Autowired
    private ObjectMapper mapper; // 요청을 보낼 때 객체를 json 으로

    @Autowired
    private MockMvc mockMvc; // 컨트롤러에 요청을 보낼 때

    @Autowired
    private MemberJpaRepository memberJpaRepository;

    @Autowired
    private MemberJoinService memberJoinService;

 

@SpringBootTest 를 붙이는 것은 당연하고

@AutoConfigureMockMvc 애노테이션도 붙여준다. 이게 뭐냐면

 

모형 웹 환경을 가져와서 테스트 할 수 있는 것이다

Controller 는 웹 서버와 통신하며 동작하니까 가짜 웹 서버와 통신하는 척 하기 위해 이게 필요하다

 

 

 

    @Autowired
    private ObjectMapper mapper; // 요청을 보낼 때 객체를 json 으로

    @Autowired
    private MockMvc mockMvc; // 컨트롤러에 요청을 보낼 때

 

그리고 요청을 보낼 때 객체를 json 으로 보내기 위한 ObjectMapper 객체와

컨트롤러에 가짜 요청(?)을 보내기 위한 MockMvc 객체를 가져온당 ! !

 

 

 

자 그럼 이제 테스트를 해볼까??

 

 

    @Test
    @DisplayName("password 변경 시 짧으면 BadRequest")
    void modifyPwd() throws Exception {
        // given
        Member member = getMember();
        member = memberJoinService.joinMember(member);

        MockHttpSession session = new MockHttpSession();
        session.setAttribute("id", member.getId());

        PwdDto pwdDto = new PwdDto("password!123", "newPw");
        // expected
        mockMvc.perform(
                put("/info/password")
                        .session(session)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(mapper.writeValueAsString(pwdDto))
        ).andExpect(status().isBadRequest())
         .andExpect(jsonPath("$.data").value("BAD_FORM"))
         .andDo(print());
    }

 

컨트롤러에 대한 테스트는 given -> expected(예상결과) 로 이루어지는데

뭐 Controller 에 있는 로직이 when 이기 때문이겠징?

 

 

 

        // given
        Member member = getMember();
        member = memberJoinService.joinMember(member);

        MockHttpSession session = new MockHttpSession();
        session.setAttribute("id", member.getId());

        PwdDto pwdDto = new PwdDto("password!123", "newPw");

 

일단 given 에서 주목해야할 것은 MockHttpSession 객체이다

이건 가짜 세션 객체를 만들어주는 객체인데 이게 왜 필요했냐면

 

 

    @ResponseBody
    @PutMapping("/password")
    public ResponseEntity<String> modifyPwd(@RequestBody @Valid PwdDto pwdDto, HttpServletRequest request) {
        try {
            Long id = webService.getIdInSession(request);

내 컨트롤러에서는 일단 세션에 있는 id 를 가져와서 그 id 로 멤버 객체를 찾기 때문이당ㅇ_ㅇ

그래서 session 에서 id 를 꺼내오는 것이 필수 작업이다 !!

 

 

 

 

        // expected
        mockMvc.perform(
                put("/info/password")
                        .session(session)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(mapper.writeValueAsString(pwdDto))
        ).andExpect(status().isBadRequest())
         .andExpect(jsonPath("$.data").value("BAD_FORM"))
         .andDo(print());

그리고 예상 결과를 써내려가면 되는데

 

put("/info/password") 해당 도메인으로 요청
.session(session) 필요한 세션을 집어넣기(아까 만든 Mock 객체 넣음)
.contentType(MediaType.APPLICATION_JSON) 내가 보내는 자원은 json 형식으로 이루어져 있음
.content(mapper.writeValueAsString(pwdDto)) Json 으로 이루어져있는 PwdDto를 요청에 넣는다(아까 만든 오브젝트 매퍼)

 

이렇게 요청을 한 후

 

 

결과로는

.andExpect(status().isBadRequest()) BadRequest 라고 응답이 올 것
.andExpect(jsonPath("$.data").value("BAD_FORM")) // BODY 에는 data 로 BAD_FORM 이라고 올 것
.andDo(print()); 그걸 프린트해줘

이렇게 된다고 예상한다

 

 

 

그러면 이제 테스트를 돌려볼까?

결과는?

 

 

 

예상한 400 에러가 뜨고

data 로 BAD_FORM 이라고 오는 것을 볼 수 있다

내가 예상한대로 테스트 결과가 나타났기 때문에

실패를 했지만 테스트는 성공이라고 볼 수 있다 ^____^

 

 

테스트는 즐거워!

728x90