이번엔 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 이라고 오는 것을 볼 수 있다
내가 예상한대로 테스트 결과가 나타났기 때문에
실패를 했지만 테스트는 성공이라고 볼 수 있다 ^____^
테스트는 즐거워!
'개발공부 개발새발 > JAVA' 카테고리의 다른 글
Hello, Java 21 ! (0) | 2023.09.23 |
---|---|
JAVA ) GC & JVM (0) | 2023.07.21 |
Junit5 Test ) Service 를 테스트 해보자! (0) | 2023.07.01 |
JpaRepository 를 사용하는 클래스를 테스트를 하고 싶어요! (0) | 2023.05.31 |
Dto를 파라미터로 받았을 때, 엔티티는 어느 계층에서 변환해야 좋을까? +) 바뀐 의견 추가 (0) | 2023.05.06 |