inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Practical Testing: 실용적인 테스트 가이드

Presentation Layer 테스트 (2)

컨트롤러 테스트 시 POST시 Mockito.when() 처리에서 질문드립니다.

263

GodGwan

작성한 질문수 2

2

안녕하세요 제가 좀 더 응용해서 post 요청 시에 Mockito.when()과 접목시킨 테스트를 진행해봣는데 이 과정에서 질문이 있어 질문 드립니다.

 

예시 코드는 다음과 같습니다.

void signUpTest() throws Exception {
    //given
    var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL);
    var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password");

    //when
    when(memberFacadeService.signUp(signUpRequest))
            .thenReturn(memberResponse);

    //then
    mockMvc.perform(
                    post("/api/v1/members/signUp")
                            .content(OBJECT_MAPPER.writeValueAsString(signUpRequest))
                            .contentType(MediaType.APPLICATION_JSON)
            )
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(MEMBER_ID))
            .andExpect(jsonPath("$.email").value(MEMBER_EMAIL));
}


이 코드 시에 문제가 발생합니다. 문제는 java.lang.AssertionError: No value at JSON path "$.id"

이거입니다.

 

근데, 이 코드를 아래와 같이 바꾸면 에러가 발생하지 않습니다.

void signUpTest() throws Exception {
    //given
    var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL);
    var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password");

    //when
    when(memberFacadeService.signUp(any(SignUpRequest.class))) 
            .thenReturn(memberResponse);

    //then
    mockMvc.perform(
                    post("/api/v1/members/signUp")
                            .content(objectMapper.writeValueAsString(signUpRequest))
                            .contentType(MediaType.APPLICATION_JSON)
            )
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(MEMBER_ID))
            .andExpect(jsonPath("$.email").value(MEMBER_EMAIL));
}


위와 아래의 차이는 requestBody에 들어가는 SignUpRequest 클래스를 mockBean처리 된 memberFacadeService의 when 처리 시에 해당 클래스를 any()로 처리하나 안처리하나의 차이입니다.

 

제가 예상하기에는 mockMvc에서 .content(objectMapper.writeValueAsString(signUpRequest)) 로 이렇게 처리했기 때문에 해당 로직에 들어가는 memberFacadeService 클래스의 signUp 매개변수로 들어가는 SignUpRequest가 제가 위에서 선언한 signUpRequest와 다르기 때문에 발생하는 문제라고 생각합니다.

 

이 이해가 맞는지에 대한 질문과 post요청에서는 다 이렇게 any()처리를 해야되는지 궁금합니다.

 

spring tdd jpa mockito 소프트웨어-테스트 junit5

답변 1

1

박우빈

안녕하세요, 박용관 님!

네, 맞습니다. 말씀하신 것처럼 위쪽의 mocking 로직은 특정 인스턴스에만 해당하는 mocking이기 때문에, 직렬화/역직렬화 과정을 거쳐 다시 만들어진 인스턴스는 이전에 만들었던 signUpRequest와 다른 인스턴스이기 때문에 그렇습니다.

그렇기에 아래쪽에 해주신 것처럼 특정 타입(SignUpRequest.class)에 모두 해당하는 mocking이 되도록 any()로 처리해주는 것이 맞습니다.

post 요청이라 any() 처리를 한다기 보다는, mocking하는 상황에 맞게 처리해야 한다, 로 이해하시는 것이 좋을 것 같아요 ㅎㅎ

도움이 되셨기를 바랍니다.
감사합니다. 🙂

private 상수 테스트 관련 질문

0

83

1

void는 어떻게 테스트하나요..? void로 애초에 코딩하면 안되나요??

0

126

2

커버리지는 어떻게 활용하시는지 궁금합니다.

0

161

2

테스트 문서화 질문입니다

0

105

2

단위테스트 질문이 있습니다

0

96

2

컨트롤러는 모킹을 한 이유가 궁금합니다.

0

103

2

ERD 가장자리에 있는 도메인 테스트 질문

0

89

2

DTO 검증 필드에 대한 테스트 코드 작성은 어디까지?

0

135

2

OrderCreateRequest DTO에 대해서 궁금한점

0

102

2

고전파의 테스트 대역 사용 대상, 공유 의존성

0

156

2

계층 관련 질문이 있습니다.

0

139

3

'코틀린'에서는 빌더를 따로 쓰지 않는데, 이 때는 어떻게 test fixture를 만드시는지 궁금합니다

1

124

2

혹시 update 로직은 어떻게 테스트하나요? (@Setter?)

0

134

2

단위테스트와 통합테스트의 경계가 궁금합니다.

0

228

2

Service+Repository 통합테스트 관련 질문입니다.

0

150

2

OrderControllerDocsTest 작성 해봤는데요. 날짜 형식이 이상하게 나와요

0

184

2

test 용 .yml

0

90

2

throws Exception

0

80

2

카페키오스크 클래스 문의 ,,

0

89

2

Rest docs 문서용 테스트코드를 따로 작성해야 되나요?

0

173

2

테스트 코드에서 필요한 생성자

0

138

1

tearDown 순서

0

116

2

@Builder 생성자 private

0

136

2

@DisplayName gradle / intellJ

0

93

2