Mockito에서 Mock(가짜) 객체의 의존성 주입을 위해서는 크게 3가지 어노테이션이 사용된다.
@Mock
: Mock 객체를 만들어 반환해주는 어노테이션@Spy
: Stub하지 않은 메소드들은 원본 메소드 그대로 사용하는 어노테이션@InjectMocks
: @Mock 또는 @Spy로 생성된 가짜 객체를 자동으로 주입시켜주는 어노테이션⚠️
@ExtendWith(MockitoExtension.class)
: Mockito 테스팅 프레임워크를 JUnit과 결합하기 위한 어노테이션 사용
Assertion.assertEquals(expected, result)
: 결과 값과 예상 값을 비교하여 검사@ExtendWith(MockitoExtension.class)
모킹 testfake는 동일한 인터페이스를 구축하지만 다른 객체와 상호작용하지 않고 실제 코드를 대체하는 객체다.
보통 fake는 고정된 결과를 반환하도록 하드 코딩된다. 다양한 유즈케이스를 테스트하려면 많은 페이크를 사용해야 한다.
fake의 문제는 인터페이스가 수정되면, 이 인터페이스를 수정하는 fake도 수정해야 한다는 것이다.
stub는 특정 인풋 셋을 기반으로 특정 결과를 반환하는 객체다. 일반적으로 테스트를 위해 프로그래밍 항목 이외의 항목에는 응답하지 않는다.
mock은 stub의 좀 더 정교한 버전이다. 각 메서드를 몇 번 째 호출하는지에 따라 프로그래밍할 수 있다. 어떤 데이터를 응답할건지 설정할 수 있다.
testImplementation group: 'org.mockito', name: 'mockito-core', version: '4.8.0'
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '4.6.1'
@ExtendWith(MockitoExtension.class)
public class DollarMockingTest {
@Mock
public MarketApi marketApi;
@BeforeEach
public void init(){
Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
}
@Test
@DisplayName("Dollar sum/minus test")
public void mockTest(){
// MarketApi marketApi = new MarketApi(); //MEMO: MOCK활용을 위하여 삭제
DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
dollarCalculator.init();
Calculator calculator = new Calculator(dollarCalculator);
System.out.println(calculator.sum(10, 10));
//MEMO: Assertions를 활용한 검사
Assertions.assertEquals(60000, calculator.sum(10, 10));
Assertions.assertEquals(0, calculator.minus(10, 10));
}
}
@ExtendWith(MockitoExtension.class)
어노테이션을 붙인다.MarketApi
에 @Mock
Annotation을 붙인다.Mockito.lenient().when
으로 marketApi.connet()
에서 3000원 리턴@WebMvcTest(CalculatorApiController.class)
@AutoConfigureWebMvc
@Import({Calculator.class, DollarCalculator.class})
public class CalculatorApiControllerTest {
@MockBean
private MarketApi marketApi;
@Autowired
private MockMvc mockMvc;
@BeforeEach
public void init() {
Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
}
@Test
public void sumTest() throws Exception {
// http://localhost:8080/api/sum
mockMvc.perform(
MockMvcRequestBuilders.get("http://localhost:8080/api/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(10, 10);
String json = new ObjectMapper().writeValueAsString(req);
mockMvc.perform(
MockMvcRequestBuilders.post("http://localhost:8080/api/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());
}
}
@WebMvcTest(CalculatorApiController.class)
Anotation 등록@AutoConfigureWebMvc
← Spring Mvc test를 위하여 등록@Import({Calculator.class, DollarCalculator.class})
← 사용할 클래스 불러오기(이미 Bean 등록이 되어있어 생략 가능)@MockBean
으로 등록MockMvc
불러오기MockMvc
를 이용하여 Spring Web Testing 하기perform
: 테스트 실행하기 MockMvcRequestBuilders
로 Request BuilderandExpect
: 예상값과 결과값을 비교 MockMvcResultMatchers
메소드 이용andDo
: 테스트 실행하고 할 일을 등록MockMvcResultHandlers.print()
실행 과정 출력Java 코드의 코드 커버리지를 체크 하는 라이브러리
결과를 html, xml, csv 로 확인 가능하다.
📌 Java Gradle plugins에 jacoco를 추가
plugins{ id 'jacoco' }
- jacocoTestCoverageVerification
- jacocoTestReport
Gradle → Tasks → verification에 추가된다.
Gradle → Tasks → verification 의 test를 클릭하여 테스트 가능
테스트 결과는 build/reports/tests/test/index.html 에 저장되고 chrome 등으로 열어 확인 가능하다.
jacocoTestReport 역시 비슷하게 실행 가능
build/reports/jacoco/test/html/index.html 에서 결과 report 확인 가능