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
'개인적 정리' 카테고리의 다른 글
스프링 부트와 AWS로 혼자 구현하는 웹서비스 (0) | 2022.07.10 |
---|---|
@Respository 어노테이션이 필수가 아니다? (0) | 2022.06.12 |
알고리즘 PULL 까먹지 말아보자 (0) | 2022.06.06 |
테스트 코드를 작성하기 전에 한번 읽어보자 (0) | 2022.04.11 |
JAR ,WAR 배포 차이 (0) | 2022.03.31 |