文章目录
- ArgumentMatchers
- doReturn vs When
- Verify
- Stubbing
- Matchers
- Verify Invocation Times
- Stub void with exception
- Verify in order
- Redundant invocations
- @Mock
- Consecutive calls
- 打桩返回一个较为复杂的业务处理逻辑结果
- doReturn | doThrow | doAnswer | doNothing | doCallRealMethod .when(mockedInstance).doSomething()
- Spying on real Objects
- Create mock with strategy
- @Captor @Spy @InjectMocks
- verify timeout
- ignore stub
- @RunWith(MockitoJUnitRunner.class)
- lambda support
- answer
- mock static methods
ArgumentMatchers
- any | anyObject | anyString
- anyByte | anyShort | anyBoolean | anyChar | anyInt | anyFloat | anyDouble | anyLong
- booleanThat | byteThat | charThat | doubleThat | floatThat | intThat | longThat | shortThat
- anyCollection | anyCollectionOf
- anyIterable | anyIterableOf
- anyList | anyListOf | anySet | anySetOf | anyMap | anyMapOf
- argThat
- contains | eq | isA | same | matches
- startsWith | endsWith
- isNotNull | isNull | notNull | nullable
doReturn vs When
Use doReturn() in those rare occasions when you cannot use when(Object).
Beware that when(Object) is always recommended for stubbing because it is argument type-safe and more readable (especially when stubbing consecutive calls) 方便连续调用thenReturn
首选 when,当 when() 中的语句铁定抛异常时,使用 doReturn().when()
例外情况:
1 When spying real objects and calling real methods on a spy brings side effects
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo”);
//You have to use doReturn() for stubbing:
doReturn("foo").when(spy).get(0);
2 Overriding a previous exception-stubbing
when(mock.foo()).thenThrow(new RuntimeException());
//Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown. when(mock.foo()).thenReturn("bar");
//You have to use doReturn() for stubbing:
doReturn("bar").when(mock).foo();
Adds a description to be printed if verification fails.
verify(mock, description("This will print on failure")).someMethod("some arg");
Verify
verify(mockedList).add(“one”);
Stubbing
when(mockedList.get(0)).thenReturn("first”);
when(mockedList.get(1)).thenThrow(new RuntimeException());
Matchers
when(mockedList.get(anyInt())).thenReturn("element”);
verify(mockedList).get(anyInt());
// 字符串匹配,这里要用 eq, eq 也是一个参数匹配器
verify(mock).someMethod(anyInt(), anyString(), eq(“third argument”));
Verify Invocation Times
verify(mockedList, times(2)).add("once”);
verify(mockedList, never()).add("never happened”);
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”);
Stub void with exception
doThrow(new RuntimeException()).when(mockedList).clear();
Verify in order
InOrder inOrder = inOrder(singleMock);
InOrder inOrder = inOrder(firstMock, secondMock);
inOrder.verify(singleMock).add(“was added first”);
inOrder.verify(singleMock).add("was added second”);
Redundant invocations
verifyNoMoreInteractions(mockedList);
意思是 mock除了 verify 之外被用过几次,验证无更多调用就是说该 mock只被用过一次
@Mock
MockitoAnnotations.openMocks(testClass);
or
MockitoJUnitRunner
Consecutive calls
when(mock.someMethod("some arg”))
.thenThrow(new RuntimeException()) 第一次调用返回
.thenReturn("foo”); 第二次调用返回,之后再继续调用,依然返回最后一次的stub 结果
简写
when(mock.someMethod(“some arg”)) .thenReturn(“one”, “two”, "three”);
如果重复插桩,后者会覆盖前者
打桩返回一个较为复杂的业务处理逻辑结果
when(mock.someMethod(anyString())).thenAnswer(
new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return "called with arguments: " + Arrays.toString(args);
}
});
doReturn | doThrow | doAnswer | doNothing | doCallRealMethod .when(mockedInstance).doSomething()
Spying on real Objects
When you use the spy then the real methods are called (unless a method was stubbed)
List spy = spy(list);
when(spy.size()).thenReturn(100); doReturn调用方和方法是分开的,when 直接开头调用方和方法是写在一起的
重点来了:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
when().thenReturn() 先执行when 里的方法,只不过返回值会重新处理;
doReturn().when() 会插桩,不会执行真实的方法,直接返回要返回的值
Create mock with strategy
Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
@Captor @Spy @InjectMocks
@Spy + @InjectMocks = 注入 mock 对象到 spy
verify timeout
verify(mock, timeout(100)).someMethod(); 方法执行了超过 100ms
verify(mock, timeout(100).times(2)).someMethod(); 100ms 内该方法被调用了 2 次
ignore stub
verifyNoMoreInteractions(ignoreStubs(mock, mockTwo));
InOrder inOrder = inOrder(ignoreStubs(mock, mockTwo));
@RunWith(MockitoJUnitRunner.class)
lambda support
verify(list, times(2)).add(argThat(string -> string.length() < 5));
when(mock.someMethod(argThat(list -> list.size()❤️))).thenReturn(null);
answer
doAnswer(invocation -> 12).when(mock).doSomething();
doAnswer(invocation -> ((String)invocation.getArgument(1)).length()).when(mock).doSomething(anyString(), anyString(), anyString());
doAnswer(AdditionalAnswers.answerVoid((operand, callback) -> callback.receive(“dummy”)) .when(mock).execute(anyString(), any(Callback.class));
mock static methods
To make sure a static mock remains temporary, it is recommended to define the scope within a try-with-resources construct.
try (MockedStatic mocked = mockStatic(Foo.class)) {
mocked.when(Foo::method).thenReturn("bar");
assertEquals("bar", Foo.method());
mocked.verify(Foo::method);
}
This combination of annotations is not permitted on a single field:
@Mock and @InjectMocks
PowerMock可以实现完成对private/static/final方法的Mock(模拟),而Mockito可以对普通的方法进行Mock
详见同一专栏中PowerMock相关内容
@InjectMocks:创建一个实例,简单的说是这个Mock可以调用真实代码的方法,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。
https://blog.csdn.net/qq_33378853/article/details/106918902