JUnit이란?
java기반의 단위 테스트를 위한 프레임워크
Annotation 기반으로 테스트를 지원하며, Assert를 통하여, 예상or실제를 통해 검증
// Mockito 처리를 한다 : 특정한 객체에서 원하는 메소드가 호출이 되었을 때 원하는 결과값을 리턴한다??
@ExtendWith(MockitoExtension.class)
public class DollarCalculatorTest {
@Mock // MarketApi 객체를 mock 처리한 것임
public MarketApi marketApi;
@BeforeEach
public void init(){ // marketApi.connect()가 실행될 때 메서드의 리턴값이 아니라 내가 원하는 값을 리턴함
Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
}
@Test
public void testHello(){
System.out.println("hello");
}
@Test
public void dollarTest(){
MarketApi marketApi = new MarketApi();
DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
dollarCalculator.init();
Calculator calculator = new Calculator(dollarCalculator);
System.out.println(calculator.sum(10,10));
Assertions.assertEquals(22000, calculator.sum(10,10));
Assertions.assertEquals(0,calculator.minus(10,10));
}
@Test
public void mockTest(){
DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
dollarCalculator.init();
Calculator calculator = new Calculator(dollarCalculator);
System.out.println(calculator.sum(10,10));
Assertions.assertEquals(60000, calculator.sum(10,10));
Assertions.assertEquals(0,calculator.minus(10,10));
}
}
위 방식은 spring에서 쓰는 방식은 아님 이제 spring에서 junit을 쓰는 방식을 보자
먼저, 짚고 넘어가야할 점은 테스트할 코드의 main디렉터리와 test디렉터리 하위 경로를 일치시켜줘야 한다는 점이다.
다음은 component 하위의 객체들에 대한 테스트 코드와 controller에 대한 테스트 코드이다.
@SpringBootTest // 모든 bean이 자동 등록됨
public class DollarCalculatorSpringTest {
@MockBean // spring은 bean으로 관리하기 때문에 mock이 아닌 mockbean을 사용
private MarketApi marketApi;
@Autowired
private Calculator calculator;
@Test
public void dollarCalculatorTest(){
Mockito.when(marketApi.connect()).thenReturn(3000);
int sum = calculator.sum(10,10);
int minus = calculator.minus(10,10);
Assertions.assertEquals(60000,sum);
Assertions.assertEquals(0, minus);
}
}
@WebMvcTest(CalculatorApiController.class) // @SpringBootTest와 달리 web에 필요한 것만 로딩하기 때문에 자원소비가 덜함
@AutoConfigureWebMvc
@Import({Calculator.class, DollarCalculator.class})// 필요한 객체 주입
public class CalculatorApiControllerTest {
@MockBean
private MarketApi marketApi;
@Autowired
private MockMvc mockMvc; // Mvc를 mock으로 테스트하겠다는 것
@BeforeEach
public void init(){
Mockito.when(marketApi.connect()).thenReturn(3000);
}
@Test
public void sumTest() throws Exception { // 브라우저를 열지 않아도 테스트 가능!
// http://localhost:9090/junit/sum
mockMvc.perform(// GET 방식일때
MockMvcRequestBuilders.get("http://localhost:9090/junit/sum")
.queryParam("x","10")
.queryParam("y","10")
).andExpect(
MockMvcResultMatchers.status().isOk()
).andExpect(
MockMvcResultMatchers.content().string("60000")
).andDo(MockMvcResultHandlers.print());
}
@Test
public void minusTest() throws Exception {
Req req = new Req();
req.setX(10);
req.setY(10);
String json = new ObjectMapper().writeValueAsString(req);
mockMvc.perform(// POST 방식일 때
MockMvcRequestBuilders.post("http://localhost:9090/junit/minus")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
).andExpect(
MockMvcResultMatchers.status().isOk()
).andExpect(
MockMvcResultMatchers.jsonPath("$.result").value("0")
).andExpect(
MockMvcResultMatchers.jsonPath("$.response.resultCode").value("OK")
).andDo(MockMvcResultHandlers.print());
}
}
java코드의 코드 커버리지를 체크하는 라이브러리
결과를 html,xml,csv로 확인이 가능하다.
build.gradle의 plugins에 id 'jacoco'을 추가한다.
Gradle에서 verification의 test를 먼저 실행시킨다.
그 후 index.html을 열어보면
다음과 같은 페이지를 볼 수 있다.
jacocoTestReport를 실행시킨다.
jacoco하위의 index.html을 열어본다.
다음과 같이 내가 작성한 코드에 대한 전체적인 테스트 비율을 알 수 있다.
출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.