1. stub
메서드를 호출하면 미리 정의된 답변을 줌
- 위키피디아 : 스텁은 기존 코드(예를 들어 원격 머신의 프로시저)를 흉내 내거나 아직 개발되지 않은 코드를 임시로 대치하는 역할을 수행한다.
- Mocks Aren't Stubs : Stubs provide
canned answers
to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. canned answer
: 미리 준비된 답변- Stub은 테스트 중에 이루어진 호출에 대해 미리 준비된 답변을 제공하며, 일반적으로 테스트를 위해 프로그래밍 된 내용 이외의 항목에는 전혀 응답하지 않습니다.
2. javadoc
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html
1. Let's verifiy some behavior!
몇 가지의 동작을 확인하자
import static org.mockito.Mockito.mock;
은 static으로 선언하는 것이 코드가 깔끔해진다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@DisplayName("Mockito JavaDoc 3.10.0 API")
public class MockitoJavaDoc {
@Test
@DisplayName("1. Let's verify some behaviour!")
void step_01_test(){
//mock 생성
List mockedList = mock(List.class);
//mock 객체 사용
mockedList.add("test1");
mockedList.clear();
//verification(확인)
verify(mockedList).add("test1");
mockedList.clear();
}
}
2. How about some stubbing?
Stubbing은 어떻게 하지?
1) Step 1 : mock 객체 선언 (interface도 가능)
2) Step 2 : stubbing → stubbing 이후 method호 출시 일정한 값을 반환
3) Step 3 : mock은 null, primitive / primitive value 또는 비어있는 collection을 적절하게 반환 → 999번째 값을 반환해도 Exception이 아닌 null을 반환
4) Step 4 : verify로 검증 가능하다. 만약 stubbing 하지 않은 값을 호출한다면 케이스는 실패한다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@DisplayName("Mockito JavaDoc 3.10.0 API")
public class MockitoJavaDocStep02 {
@Test
@DisplayName("2. How about some stubbing?")
void step_02_test(){
//step1
LinkedList mockedList = mock(LinkedList.class);
//step2 stubbing
when(mockedList.get(0)).thenReturn("test2");
when(mockedList.get(1)).thenThrow(new NoSuchElementException());
//step3
assertThat(mockedList.get(0)).isEqualTo("test2");
assertThatThrownBy(() -> mockedList.get(1))
.isInstanceOf(NoSuchElementException.class);
assertThat(mockedList.get(999)).isNull();
//step4
verify(mockedList).get(1);
verify(mockedList).get(999);
verify(mockedList).get(0);
//verify(mockedList).get(2);
}
}
3. Argument matchers
Argument matcher 사용법
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : stubbing
anyInt()
로 어떤 int 값이 넘어와도 "Integer" 문자열이 리턴 가능하도록 세팅argThat()
을 통해 사용자 정의 argument 검증 가능 →ArgumentMatcher<T>
를 상속anyObject()
,eq()
등도 있다.
- Step 3 : verify를 진행할 method 호출 (호출 하지 않으면 LinkedList에 담기지 않음)
- Step 4 : verifiy로 검증 → 기본적으로 Java equals() 검증 사용
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@DisplayName("Mockito JavaDoc 3.10.0 API")
public class MockitoJavaDocStep03 {
class IsLengthGreaterThanOneArgument implements ArgumentMatcher<List> {
@Override
public boolean matches(List list) {
return String.valueOf(list.get(anyInt())).length() > 1;
}
}
@Test
@DisplayName("3. Argument matchers")
void step_03_test() {
//step1
LinkedList mockedList = mock(LinkedList.class);
//step2
when(mockedList
.get(anyInt()))
.thenReturn("Integer");
when(mockedList
.contains(argThat(new IsLengthGreaterThanOneArgument())))
.thenReturn(true);
//step3
mockedList.get(1);
mockedList.get(999);
mockedList.get(0);
mockedList.get(2);
//step4
verify(mockedList).get(1);
verify(mockedList).get(999);
verify(mockedList).get(0);
verify(mockedList).get(2);
}
}
4. Verifying exact number of invocations / at least x / never
Method 호출 횟수 계산하기
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : stubbing
- "once" : 1 회 add
- "twice" : 2 회 add
- "three times" : 3회 add
- Step 3 : verify에 times로 호출 횟수 검증
times(int)
- 지정한 횟수 만큼 호출 되었는 지 검증 → 기본 값은 times(1)
- Step 4 : verifiy에 제공 함수를 통해 호출 횟수 검증
never()
: 호출되지 않았는지 여부 검증atLeastOnce()
: 적어도 한번은 호출 되었는 지 검증atLeast(int)
: 적어도 지정한 횟수 만큼 호출 되었는 지 검증atMost(int)
: 최대 지정한 횟수 만큼 호출 되었는 지 검증
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.atMostOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep04 {
@Test
@DisplayName("4. Verifying exact number of invocations / at least x / never")
void step_04_test(){
//step1
LinkedList mockedList = mock(LinkedList.class);
//step2
mockedList.add("once");
mockedList.add("twice");
mockedList.add("twice");
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
//step3
verify(mockedList).add("once");
verify(mockedList, times(1)).add("once");
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");
//step4
verify(mockedList, atMostOnce()).add("once");
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("three times");
verify(mockedList, atMost(5)).add("three times");
}
}
5. Stubbing void methods with exceptions
void Method의 Stubbing 방법
- 방법 1.
doThrow
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : stubbing →
anyInt()
로 어떠한 값이 들어와도RuntimeException
발생 - Step 3 :
assertThatThrownBy
로 mockedList에서 조회 시RuntimeException Throw
발생 확인
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep05 {
@Test
@DisplayName("5. Stubbing void methods with exceptions")
void step_05_test(){
//step1
List mockedList = mock(List.class);
//step2
doThrow(new RuntimeException()).when(mockedList).get(anyInt());
//step3
assertThatThrownBy(() -> mockedList.get(1))
.isInstanceOf(RuntimeException.class);
assertThatThrownBy(() -> mockedList.get(1001))
.isInstanceOf(RuntimeException.class);
}
}
- 방법 2.
doNothing
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : stubbing →
doNothing
으로 반환값 없음으로 설정 - Step 3 : method 실행
- Step 4 : verify 검증
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep05 {
@Test
@DisplayName("5. Stubbing void methods with exceptions")
void step_05_2_test(){
//step1
List mockedList = mock(List.class);
//step2
doNothing().when(mockedList).clear();
//step3
mockedList.clear();
//step3
verify(mockedList).clear();
}
}
6. Verification in order
호출 순서 검증
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : stubbing
- Step 3 : InOrder에 mock 전달
- Step 4 : InOrder를 통해 메소드 호출 순서 검증
- Step 5 : mock 객체 선언 (interface도 가능) → 2개의 다른 객체
- Step 6 : stubbing
- Step 7 : InOrder에 두개의 mock 객체 전달
- Step 8 : InOrder를 통해 메소드 호출 순서 검증 → 2개의 다른 객체도 검증이 가능
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import java.util.List;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep06 {
@Test
@DisplayName("6. Verification in order")
void step_06_test(){
//step1
List singleMock = mock(List.class);
//step2
singleMock.add("was added first");
singleMock.add("was added second");
//step3
InOrder inOrder = inOrder(singleMock);
//step4
inOrder.verify(singleMock).add("was added first");
inOrder.verify(singleMock).add("was added second");
//step5
List firstMock = mock(List.class);
List secondMock = mock(List.class);
//step6
firstMock.add("was called first");
secondMock.add("was called second");
//step7
InOrder inOrderTwo = inOrder(firstMock, secondMock);
//step8
inOrderTwo.verify(firstMock).add("was called first");
inOrderTwo.verify(secondMock).add("was called second");
}
}
7. Making sure interaction(s) never happened on mock
다수의 객체가 사용되지 않았음을 검증
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 :
verifyNoInteraction
로 객체의 사용 유무 검증 →verifyZeroInteractions
는deprecated
됨
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.~~verifyZeroInteractions~~;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep07 {
@Test
@DisplayName("7. Making sure interaction(s) never happened on mock")
void step_07_test(){
//step1
List mockListOne = mock(List.class);
List mockListTwo = mock(List.class);
//step2
//~~verifyZeroInteractions~~(mockListOne,mockListTwo);
verifyNoInteractions(mockListOne, mockListTwo);
}
}
8. Finding redundant invocations
중복 호출 찾기 (과도한 사용은 유지 관리가 어려움)
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : mockList에 add를 두번 실행 → "one", "two" 추가
- Step 3 : verify로 add("one") 실행검증 → 1회 실행
- Step 4 :
verifyNoMoreInteractions
으로 추가 검증 실행여부 확인 → add("two")에 대한 검증은 수행되지 않음 →Fail
- 만약 "two"에 대한 verify가 추가 된다면 →
Success
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep08 {
@Test
@DisplayName("8. Finding redundant invocations")
void step_08_test(){
//step1
List mockList = mock(List.class);
//step2 stubbing
mockList.add("one");
mockList.add("two");
//step3
verify(mockList).add("one");
//verify(mockList).add("two");
//step4
verifyNoMoreInteractions(mockList);
}
}
9. Shorthand for mocks creation - @Mock annotation
빠르게 mock 생성하기 (@Mock annotation)
- Minimizes repetitive mock creation code. (반복적인 mock의 생성 최소화)
- Makes the test class more readable. (가독성 증가)
- Makes the verification error easier to read because the field name is used to identify the mock. (필드 명으로 mock을 식별하기 때문에 에러에 대한 파악이 더 쉽다.)
- This needs to be somewhere in the base class or a test runner. (반드시 작성해 주어야함) → 내장된 runner 사용 가능(
MockitoJUnitRunner
) / rule은MockitoRule
**MockitoAnnotations.initMocks
은deprecated
됨**
MockitoAnnotations.openMocks(this);
//MockitoAnnotations.~~initMocks~~(this);
- Step 1 :
MockitoAnnotations.openMocks(this)
Runner 사용 → Test Class의 Person 선언부에@Mock
Annotation 삽입 - Step 2 : stubbing →
when
을 통해 Person의 getName 값 stubbing - Step 3 : assertThat을 통해 getName 검증
- Step 4 : verify 확인
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class Person {
private Long id;
private String name;
public Person() {
}
public Person(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep09 {
@Mock
private Person person;
@Test
@DisplayName("9. Shorthand for mocks creation - @Mock annotation")
void step_09_test(){
//step1
MockitoAnnotations.openMocks(this);
//step2
when(person.getName()).thenReturn("psjw");
//step3
assertThat(person.getName()).contains("psjw");
//step4
verify(person).getName();
}
}
10. Stubbing consecutive calls (iterator-style stubbing)
연속적으로 다른 stubbing 하기
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : Stubbiing →
thenReturn
으로 2회,thenThrow
1회 Stub - Step 3 : return 세팅 순으로 호출하여 데이터 검증
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep10 {
@Test
@DisplayName("10. Stubbing consecutive calls (iterator-style stubbing)")
void step_10_test(){
//step1
List<String> mockedList = mock(List.class);
//step2
when(mockedList.get(anyInt()))
.thenReturn("one")
.thenReturn("two")
.thenThrow(new RuntimeException());
//step3
assertThat(mockedList.get(0)).isEqualTo("one");
assertThat(mockedList.get(0)).isEqualTo("two");
assertThatThrownBy(() -> mockedList.get(0))
.isInstanceOf(RuntimeException.class);
}
}
11. Stubbing with callbacks
Answer로 Callback을 Stubbing 함
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : Stubbiing →
thenAnswer
를 통해 Callback 함수 정의 → Lambda 식으로도 가능 - Step 3 : return 값 점검
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep11 {
@Test
@DisplayName("11. Stubbing with callbacks")
void step_11_test() {
//step1
List<String> mockedList = mock(List.class);
//step2
when(mockedList.get(anyInt()))
.thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] objects = invocationOnMock.getArguments();
Object mock = invocationOnMock.getMock();
return "called with arguments : " + Arrays.toString(objects);
}
});
/*
when(mockedList.get(anyInt()))
.thenAnswer(invocationOnMock -> {
Object[] objects = invocationOnMock.getArguments();
Object mock = invocationOnMock.getMock();
return "called with arguments : " + Arrays.toString(objects);
});
*/
//step3
assertThat(mockedList.get(0)).isEqualTo("called with arguments : [0]");
}
}
12. doReturn()|doThrow()| doAnswer()|doNothing()|doCallRealMethod() family of methods
doReturn(), doThrow(), doAnswer(), doNothing(), doCallRealMethod() 은 when() 함수에서 호출 됨
[doReturn(Object)](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doReturn-java.lang.Object-)
[doThrow(Throwable...)](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doThrow-java.lang.Throwable...-)
[doThrow(Class)](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doThrow-java.lang.Class-)
[doAnswer(Answer)](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doAnswer-org.mockito.stubbing.Answer-)
[doNothing()](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doNothing--)
[doCallRealMethod()](https://javadoc.io/static/org.mockito/mockito-core/3.10.0/org/mockito/Mockito.html#doCallRealMethod--)
13. Spying on real objects
spy 메서드를 통해 실제 객체에 대한 mock을 생성
- spy 객체를 사용하면 실제 매서드 호출됨 (not stubbing)
- 그렇다고 실제 객체의 호출을 위임하는게 아니라 복사본을 생성
- 그러므로 실제 객체에 영향은 없다
- final Method를 mock하지 않음
- Step 1 : ArrayList객체를 생성 후 spy 객체 생성
- Step 2 : Stubbiing → when을 먼저 사용하면 예외 발생 → doReturn을 먼저 사용해야 됨
- Step 3 : spy객체의 method실행
- Step 4 : return 값 점검 → spy 객체는 "one'을 return → 실제 mockedList 객체에서는 Exception 발생
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep13 {
@Test
@DisplayName("13. Spying on real objects")
void step_13_test() {
//step1
final List mockedList = new ArrayList();
final List spy = spy(mockedList);
//step2
//when(spy.size()).thenReturn(100);
doReturn("one").when(spy).get(0);
//step3
spy.add("one");
spy.add("two");
//step4
assertThat(spy.get(0)).isEqualTo("one");
assertThatThrownBy(() -> mockedList.get(0))
.isInstanceOf(IndexOutOfBoundsException.class);
}
}
14. Changing default return values of unstubbed invocations (Since 1.7)
Stub 되지 않은 Method를 호출할 때 default 값을 지정
- 일반적으로 사용하지 않지만 legacy 시스템 작업에도 도움이 될 수 있음
Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
- Step 1 : mock 객체를 생성 후 Name 필드의 반환값이 Null인지 체크
- Step 2 :
RETURNS_SMART_NULLS
를 활용하여 반환값이 Null이 아니고 Name 필드는 ""으로 반환 확인
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_SMART_NULLS;
import static org.mockito.Mockito.mock;
class Person2 {
private Long id;
private String name;
public Person2() {
}
public Person2(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep14 {
@Test
@DisplayName("14. Changing default return values of unstubbed invocations (Since 1.7)")
void step_14_test() {
//step1
Person2 mockedP = mock(Person2.class);
assertThat(mockedP.getName()).isNull();
//step2
Person2 mockedSmartP = mock(Person2.class, RETURNS_SMART_NULLS);
assertThat(mockedSmartP.getName()).isNotNull();
assertThat(mockedSmartP.getName()).isEqualTo("");
}
}
15. Capturing arguments for further assertions (Since 1.8.0)
Capturing arguments를 통한 검증
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : add method 실행 → 2 회
- Step 3 :
ArgumentCaptor
의forClass(클래스)
메서드를 통해 String.class를 세팅하고, add의 input 값 capture() → "one", "two" - Step 4 :
ArgumentCaptor
의allValues()
함수로 리스트로 반환 받음
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep15 {
@Test
@DisplayName("15. Capturing arguments for further assertions (Since 1.8.0)")
void step_15_test() {
//step1
List mockedList = mock(List.class);
//step2
mockedList.add("one");
mockedList.add("two");
//step3
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
verify(mockedList, times(2)).add(argumentCaptor.capture());
//step4
final List<String> allValues = argumentCaptor.getAllValues();
assertThat(allValues.get(0)).isEqualTo("one");
assertThat(allValues.get(1)).isEqualTo("two");
}
}
16. Real partial mocks (Since 1.8.0)
spy를 통해 partial mock을 사용할 수 있음.
- Step 1 : spy() method로 partial mock 생성 가능
- Step 2 : mock에 대해 선택적으로 partial mock 기능을 동작 시킬 수 있음
- Step 3 : 실제 구현이 안전하다는 것을 확인 → 만약 실제 구현이 Exception or 특정 객체의 상태에 의존하면 문제가 있다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
class Person3 {
private Long id;
private String name;
public Person3() {
}
public Person3(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep16 {
@Test
@DisplayName("16. Real partial mocks (Since 1.8.0)")
void step_16_test() {
//step1
List list = spy(new LinkedList());
//step2
Person3 mock = mock(Person3.class);
//step3
when(mock.getName()).thenCallRealMethod();
}
}
17. Resetting mocks (Since 1.8.0)
mock은 stubbing 초기화가 가능함
- Step 1 : mock 객체 선언 (interface도 가능)
- Step 2 : Stubbing
- Step 3 : mock 결과확인 → mock stub 확인
- Step 4 : mock reset
- Step 5 : mock 결과 확인 → mock stub 초기화 확인 0건
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep17 {
@Test
@DisplayName("17. Resetting mocks (Since 1.8.0)")
void step_17_test() {
//step1
List mock = mock(List.class);
//step2
when(mock.size()).thenReturn(10);
mock.add(1);
//step3
assertThat(mock.size()).isEqualTo(10);
//step4
reset(mock);
//step5
assertThat(mock.size()).isEqualTo(0);
}
}
18. Troubleshooting & validating framework usage (Since 1.8.0)
FAQ : https://github.com/mockito/mockito/wiki/FAQ
19. Aliases for behavior driven development (Since 1.8.0)
BDD(Behavior Driven Developmen)은 method에 기본으로 //given, //when, //then 을 주석을 사용
when
을 이용한 구문이BDD
의//given
,//when
,//then
주석에 맞지 않음 → stubbing은 given에 속함.- Step 1 :
given
→ mock 객체 선언 및 given을 통해 stubbing - Step 2 :
when
→ method 호출 - Step 3 :
then
→ return 결과 확인
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@DisplayName("Mockito JavaDoc 3.10.0 API")
class MockitoJavaDocStep19 {
@Test
@DisplayName("19. Aliases for behavior driven development (Since 1.8.0)")
void step_19_test() {
//step1 : given
List<String> mockedList = mock(List.class);
given(mockedList.get(0)).willReturn("one");
//when
String value = mockedList.get(0);
//then
assertThat(value).isEqualTo("one");
then(mockedList).should(times(1)).get(0);
}
}