본문 바로가기
개인적 정리

테스트 코드

by 설이주인 2022. 4. 17.

Mock

If you want to be safe and avoid calling external services and just want to test the logic inside of the unit, then use mock. - 실제 코드 response에 영향을 주면 안될때 사용 (99프로 사용)

 

InjectMock

@Mock은 mock 객체를 생성한다. 반면 @InjectMocks는 실제 객체를 생성하고 mock 의존성을 주입한다.

ex) sevice 단위 테스트에서 service의 행위를 위해서 repository가 요구 되는 상황에서 작성

@InjectMocks
ExampleService exampleService;

@Mock
ExampleRepository exampleRepository;

 

Spy (vs Mock)

mock : fake object

spy : real object

// 해당 경우 확인

 

stub (행위)

Stubs are the objects that hold predefined data and uses it to give responses during tests.

Stubs are used when we don't want to use objects that would give a response with real data

 

 


TEST CASE 작성 기본 작업

    /**
     * The Object mapper
     */
    @Autowired
    protected ObjectMapper objectMapper;
    /**
     * The Mock mvc
     */
    @Autowired
    private MockMvc mockMvc;

    private RestDocumentationResultHandler document;
 
 @BeforeEach
    public void beforeEach(WebApplicationContext webApplicationContext,
                           RestDocumentationContextProvider restDocumentation) {
        this.document = MockMvcRestDocumentation.document(
                "{class-name}/{method-name}", // 문서 경로 설정
                Preprocessors.preprocessRequest( // Request 설정
                        Preprocessors.modifyUris(),
                        Preprocessors.prettyPrint() // 정리해서 출력
                ),
                Preprocessors.preprocessResponse(Preprocessors.prettyPrint()) // Response 설정. 정리해서 출력
        );

        this.mockMvc = MockMvcBuilders // MockMvc 공통 설정. 문서 출력 설정
                .webAppContextSetup(webApplicationContext)
                .addFilter(new CharacterEncodingFilter("UTF-8", true))
                .apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation))
                .alwaysDo(document)
                .build();
    }

단건 조회 EX)

@Test
@DisplayName("단건 조회")
public void getOneBoard() throws Exception {
    //정석
    log.info("------------------------ START ------------------------");
    MvcResult mvcResult = mockMvc.perform(RestDocumentationRequestBuilders
                    .post("/create/board")
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(BoardRequest
                            .builder()
                            .title("TITLE TEST")
                            .contents("CONTENT TEST")
                            .build())))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();

    JsonNode jsonNode = objectMapper.readTree(mvcResult.getResponse().getContentAsString());
    long id = jsonNode.get("id").asLong();

    mockMvc.perform(RestDocumentationRequestBuilders
                    .get("/get/board/{id}", id)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON))
            .andDo(MockMvcResultHandlers.print())
            .andDo(document.document(
                    RequestDocumentation.pathParameters(
                            RequestDocumentation.parameterWithName("id").description("일련번호")
                    ),
                    PayloadDocumentation.responseFields(
                            PayloadDocumentation.fieldWithPath("data").type(JsonFieldType.OBJECT).description("본문"),
                            PayloadDocumentation.fieldWithPath("data.title").type(JsonFieldType.STRING).description("제목"),
                            PayloadDocumentation.fieldWithPath("data.contents").type(JsonFieldType.STRING).description("내용")
                    )
            ))
            .andExpect(MockMvcResultMatchers.status().isOk());

    log.info("------------------------ END ------------------------");
}

 

ObjectMapper

ObjectMapper provides functionality for reading and writing JSON, 자동 매핑

.writeValueAsString  - 알아서 생각

.....생략......
.content(objectMapper.writeValueAsString(BoardRequest
                                .builder()
                                .title("TITLE TEST")
                                .contents("CONTENT TEST")
                                .build()))

JsonNode

Base class for all JSON nodes, which form the basis of JSON Tree Model that Jackson implements. 

One way to think of these nodes is to consider them similar to DOM nodes in XML DOM trees.

JsonNode jsonNode = objectMapper.readTree(mvcResult.getResponse().getContentAsString());

objectMapper.readTree

public com.fasterxml.jackson.databind.JsonNode readTree(     
String content 
)
throws com.fasterxml.jackson.core.JsonProcessingException,
	com.fasterxml.jackson.databind.JsonMappingException

 

MockMvcResultHandler.print()

더보기

.print()이 출력하는 정보 

 

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /create/board
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"48"]
             Body = {"title":"TITLE TEST","contents":"CONTENT TEST"}
    Session Attrs = {}

Handler:
             Type = com.example.demo.controller.BoardController
           Method = com.example.demo.controller.BoardController#createBoard(BoardRequest)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json;charset=UTF-8"]
     Content type = application/json;charset=UTF-8
             Body = {"id":1}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

/**
 * Print {@link MvcResult} details to the "standard" output stream.
 * @see System#out
 * @see #print(OutputStream)
 * @see #print(Writer)
 * @see #log()
 */
public static ResultHandler print() {
   return print(System.out);
}

RestDoc

document

.... 생략
.andDo(document.document(
                        RequestDocumentation.pathParameters(
                                RequestDocumentation.parameterWithName("id").description("일련번호")
                        ),
                        PayloadDocumentation.responseFields(
                                PayloadDocumentation.fieldWithPath("data").type(JsonFieldType.OBJECT).description("본문"),
                                PayloadDocumentation.fieldWithPath("data.title").type(JsonFieldType.STRING).description("제목"),
                                PayloadDocumentation.fieldWithPath("data.contents").type(JsonFieldType.STRING).description("내용")
                        )
                )

restdocument 작성 //swager :: dto

 

 

Git 주소 : https://github.com/EssLemint/test-code-board