1. Mock 객체 만들기
// Mockito.mock(타겟 인터페이스);
List mockitoList = Mockito.mock(List.class);
mockitoList.add("value");
// 스텁(Stub)을 하지않았을 경우, 리턴타입에 따라 기본값을 리턴한다.
System.out.println(mockitoList.contains("value")); // false
System.out.println(mockitoList.get(0)); // null
System.out.println(mockitoList.size()); // 0
2. 테스트에 사용할 스텁 생성 및 검증
import static org.mockito.Mockito.*;
...
// 2.0 객체 생성
@Before
public void setUp() {
mockedList = mock(List.class); // Mock객체 만들기
}
// 2.1 when(Mock객체 메소드).thenReturn(리턴할 값);
@Test
public void testWhenReturn() {
// 예상값 지정.
when(mockedList.get(0)).thenReturn("item"); // mockedList.get(0) 호출 시 "item"을 리턴한다.
when(mockedList.size()).thenReturn(100); // mockedList.size() 호출 시 100을 리턴한다
// 예상값 확인.(콘솔에 출력)
System.out.println(mockedList.get(0)); // item
System.out.println(mockedList.size()); // 100
System.out.println(mockedList.get(2)); // null
// 메소드 호출
mockedList.add("item");
mockedList.add("item");
// 검증
// 3.1 verify(Mock객체).Mock객체_메소드(); // void
// 3.2 verify(Mock객체).Mock객체_메소드(Object); // parameter가 있는경우
// 3.3 verify(Mock객체, 호출횟수지정_메소드).Mock객체_메소드(); // void
// 3.4 verify(Mock객체, 호출횟수지정_메소드).Mock객체_메소드(Object); // parameter가 있는경우
verify(mockedList, atLeastOnce()).add("item"); // atLeastOnce() : mockedList.add("item")가 1번이상 실행 됨.
verify(mockedList, times(2)).add("item"); // times(2) : mockedList.add("item")가 2번 실행됨.
verify(mockedList).size(); // mockedList.size()가 1번 실행됨.
verify(mockedList, atLeastOnce()).get(0);
verify(mockedList, atLeastOnce()).get(2);
verify(mockedList, atLeastOnce()).get(anyInt()); // 아무 int값이나 1번이상 실행
verify(mockedList, never()).contains("실행안됨"); // 실행안됨.
}
// 2.2 when(Mock객체 메소드).thenThrow(발생시킬 예외);
@Test
public void testWhenThrow() {
// 예상값 지정.
when(mockedList.get(1)).thenThrow(new RuntimeException()); // mockedList.get(1) 호출 시 throw new RuntimeException();
try {
System.out.println(mockedList.get(1)); // Exception이 발생하여 출력하지 않음.
} catch (RuntimeException e) {
System.out.println(e.getClass().getName()); // RuntimeException
}
verify(mockedList).get(1);
}
※ 호출횟수 지정 메소드 종류
verify(객체, 호출횟수지정메소드).객체메소드();
미지정시 | times(1) |
times(n) | n번 호출됐는지 확인. |
never() | 호출되지 않았어야 함 |
atLeastOnce | 최소 한번이상 호출 |
atLeast(n) | n번 이상호출 |
atMost(n) | n번이상 호출되면 안됨. |
※ Mock객체메소드 파라메터 종류
verify(객체, 호출횟수지정메소드).객체메소드(파라메터);
any | |
any 타입 | anyInteger(), anyBoolean() 등 java타입에 해당하는 any타입들이 있다. |
anyCollection anyCollectionOf |
List, Map, Set 등 Collection 객체일때 OK. anyCollectionOf는 anyCollection과 동일하며 자연스러운 문장을 위해 사용. |
argThat(HamcrestMatcher) | Hamcrest Matcher를 사용하고자 할때 |
eq | Argument Matcher가 한번 사용된 부분에서 Java의 타입을 그대로 사용할 수 없다. 그럴때 eq를 이용한다. verify(mock).add(anyString(), "item"); // 사용불가 verify(mock).put(anyString(9), eq("item")); // 사용가능 |
anyVararg | 여러개의 인자를 지칭할 때 사용한다. // Stub when(mock.foo(anyVararg())).thenReturn(100); // 여러인자 들어왔을때 100 리턴. // Verify mock.foo(1, 2); mock.foo(1, 2, 3, 4); verify(mock, times(2)).foo(anyVararg()); // 여러 인자로 메소드가 2번 호출됨. |
matches(String regex) | 정규식 문자열로 대상을 지칭한다. |
startsWith(String) endWith(String) |
특정 문자열로 시작하거나 끝나면 OK |
anyList anyMap anySet |
anyCollection의 디테일한 버전. |
isA(Class) | 해당 클래스 타입이기만 하면 OK |
isNull | null이면 OK |
isNotNull | null만 아니면 OK |
※ void메소드를 Stub으로 만들기
// doThrow(예외).when(Mock객체).voidMethod();
doThrow(new RuntimeException()).when(mockList).clear();
※ 콜백으로 Stub만들기(thenAnswer)
when(rs.getInt("no")).thenAnswer(new Answer<Integer>(){
public Integer answer(InvocationOnMock invocation) throws Throwable {
...
return value;
}
});
※ 행위 주도 개발(BDD) 스타일
import static org.mockito.BDDMockito.*;
...
Seller seller = mock(Seller.class);
Shop shop = new Shop(seller);
public void shouldBuyBread() {
// given
given(seller.askForBread()).willReturn(new Bread());
// when
Goods goods = shop.buyBread();
// then
assertThat(goods, containBread());
}
'Back-End > Java' 카테고리의 다른 글
MySQL-jOOQ BigDecimal 캐스팅 다루기 (0) | 2022.03.26 |
---|---|
인텔리J Entity Class에 @Table(name), @Column(name) 빨간줄 끄는방법 (0) | 2020.06.12 |
JAVA 자소 분리된 단어 합치기 (2) | 2020.04.30 |
직접 작성해보는 java map, filter, reduce, curry (0) | 2019.10.28 |
함수형 JAVA코딩01 (0) | 2019.06.06 |