Junit으로 TDD를 실천하면서 어떻게 코드를 테스트 해야하는지 감이 잡혀온다.
알게 된 점은 아래와 같다.
1. 테스트 코드 작성법
2. 고민되는 부분
3. MockMvc의 사용법
4. Assert 사용법
1. 테스트 코드 작성법
처음에 접근할 때는 로컬 디비에 있는 데이터를 테스트하겠다는 의도로 접근했다.
하지만 디비에 있는 값을 CRUD하는 서비스의 테스트 코드를 작성했을 때, 값 검증을 위해 하드코딩된 값을 넣어야 했는데
이 때, 어떤 데이터가 나올 지 몰라 예상 데이터를 하드코딩할 수 없었다.
테스트 코드 작성 시에는 테스트 하려는 로직을 위해 디비에 데이터를 셋팅해 주어야 한다.
이 것은 2가지 방법이 있는데, @Before로 지정된 메소드 안에 구현하는 방법과 @Test 메소드의 로직 상단에 구현하는 방법이다.
셋팅한 데이터를 예상값으로 하드코딩하면서 로직이 정상적으로 수행이 되는 지 확인하며 마지막에는 디비에 임시로 저장한 레코드 데이터를 삭제해야 한다.
삭제 로직은 @After 메소드, @Test 메소드 최 하단의 위치시키면 된다.
2. 고민되는 부분
1) 아직도 로직을 Controller로 테스트를 해야 하는지, Service로 테스트 해야 하는지에 고민된다.
Ajax 통신을 하게 될 경우 Controller는 json Object를 클라이언트에 반환할텐데
이 때 json을 반환하는 로직은 서비스이기 때문에 서비스로 테스트를 진행하면 될 것 같기도 하지만 이 부분은 컨트롤러에서도 테스트가
가능하기 때문에 아직까지도 고민이 되는 부분이다.
(뭐 간단한 requestMapping에 의해 redirectedUrl, status 등을 확인하는 거라면 Controller로 테스트하면 되고,
특정 서비스 로직을 확인하고 싶다면 서비스 로직을 테스트하면 된다.)
2) 존재 유무 -> 자료형 -> 데이터의 형태를 단계로 테스트하는게 좋은 건가?
Controller의 json 데이터를 검증하기 위해 테스트를 진행하면서 exists(), is자료형(), value() 메소드들을 알게 되었고,
exists()
is자료형()
value()
순으로 데이터를 검증하고 있었다.
하지만 value() 하나만으로도 데이터의 존재 유무, 자료형, 값을 다 검증할 수 있다. 그렇다보니 굳이 exists(), is자료형()을 써야하는지도 고민이 되며 안그래도 긴 테스트 코드를 더 길게 만드는 것은 아닌지 작성할 때마다 고민이다.
3. MockMvc의 사용법
1) perform() : url 요청을 할 때 사용한다.
mockMvc.perform(
post("url")
.param("key", "value")
...
.session((mockMvcHttpSession)session 변수) //세션을 이용해야 할 때 사용
.with(csrf()) //스프링 시큐리티 csrf 사용 시
)
2) andDo() : perform 이후 실행할 행위들 선언
mockMvc.perform(...).andDo()
andDo(print()) : 요청과 응답의 상태를 콘솔에 표시
andExpect를 선언하려면 andDo()를 먼저 선언해야 함.
3) andExpect() : 예상 값을 검증한다.
mockMvc.perform()
.andExpect()
(1) status() : 상태를 검증한다.
.andExpect(status().isOk()) //http 상태 코드 200
(2) content() : response body를 검증
.andExpect(content().contentType("text/plain;charset=UTF-8")) // contentType 검증
(3) jsonPath() : json 데이터를 검증
jsonPath("$") : 최상위
jsonPath("$.depth1") : depth1
jsonPath("$.depth1.depth2") : depth2
jsonPath("경로").exists() : 경로가 존재?
jsonPath("경로").is자료형() : 경로의 값이 특정 자료형?
jsonPath("경로").value("예상 값") : 경로의 값이 예상 값?
실제 사용 : .andExpect(jsonPath("경로").exists())
(4) andReturn(), getRequest(), getSession()
andReturn() : MvcResult 객체를 반환
MvcResult : response, request 등의 정보를 가지고 있으며
mvcResult객체.getResponse().getContentAsString(); 으로 response값을 String으로 빼낼 수 있음
getRequest() : 리퀘스트 정보를 얻음.
getSession() : 세션 정보를 얻음
4. Assert 사용법
org.hamcrest.MathcerAssert.*
org.hamcrest.Mathcer.*
패키지를 많이 씀.
AssertThat(비교할 값, 예상 데이터) 형태로 작성하며
AssertThat("aaaa", equalTo("aaaa"));
AssertThat("aaaa", is("aaaa"));
등으로 비교 가능하며 is()는 deprecated 되어 있으므로 equalTo를 사용하는 것을 권장함.
더 많은 내용을 보시려면 아래를 참고하세요.
블로그의 다른 글
'[개발] Test' 카테고리의 다른 글
JUnit Test code setup (0) | 2023.11.13 |
---|---|
과연 TDD를 제대로 알고 있는 걸까? (0) | 2022.03.27 |
JUnit (0) | 2018.01.27 |
TDD(Test Driven Development) (0) | 2018.01.23 |
JUnit - initializationError 해결하기 (6) | 2017.12.09 |