Mockito
Mock测试即在测试过程中,对于一些不容易构造的,与本次单元测试关系不大但又有上下文依赖关系的对象,用一个虚拟的对象(Mock对象)来模拟,以便单元测试能够进行。Mockito是Java单元测试的mock开源框架。
手册:mockito-core 3.11.2 javadoc ()
常用方法:
mock对象:
@BeforeEach void init() { scheduler = mock(); scheduleService = new ScheduleServiceImpl(scheduler); }
参数匹配:
anyInt()、anyLong()、anyFloat()、anyDouble(),匹配任意xx类型数据
@Test void testMoc(){ ArrayList test = mock(); when((anyInt())).thenReturn("mock argumentMatcher"); ((0)); }
设置对象调用的预期返回值:
when(condition).thenReturn(value1); 当满足when中条件时候,返回value1;当不满足时候,返回null
when(condition).thenReturn(value1).thenReturn(value2); 当满足when中条件时候,第一次返回value1,第n(n>1且∈N*)次返回value2
when(condition).thenReturn(value1)...thenReturn(valuen); 当满足when中条件时候,第一次返回value1,第二次返回value2...第n(n>1且∈N*)次返回valuen
doReturn().when().someMethod(); 与thenReturn()的区别是不会调用真实方法
示例如下:
当满足when中条件时候,返回value1:
@Test void mockitoMethodWhenThen(){ ArrayList mockList = mock(); //参数匹配(when中条件不满足时候,renturn null) when((anyInt())).thenReturn("mock argumentMatcher"); ((0)); }
当不满足条件时候,返回null:
@Test void mockitoMethodWhenThen(){ ArrayList mockList = mock(); //参数匹配(when中条件不满足时候,renturn null) when((1)).thenReturn("mock argumentMatcher"); ((0)); }
当满足when中条件时候,第一次返回value1,第n次(n>1且∈N*)返回value2:
@Test void mockitoMethodWhenThen(){ ArrayList mockList = mock(); //参数匹配(when中条件不满足时候,renturn null) when((anyInt())).thenReturn("First trigger").thenReturn("Second trigger").thenReturn("Third trigger"); ((0)); ((1)); ((2)); ((2)); ((3)); }
@Test void mockitoMethodDoReturn() { ArrayList mockList = mock(); (1); doReturn((2)).when(mockList).add(3); (3); assertThat((2)).isEqualTo(2); }
API如下所示:
/** * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called. * <p> * Simply put: "<b>When</b> the x method is called <b>then</b> return y". * * <p> * Examples: * * <pre class="code"><code class="java"> * <b>when</b>(()).<b>thenReturn</b>(10); * * //you can use flexible argument matchers, : * when((<b>anyString()</b>)).thenReturn(10); * * //setting exception to be thrown: * when(("some arg")).thenThrow(new RuntimeException()); * * //you can set different behavior for consecutive method calls. * //Last stubbing (: thenReturn("foo")) determines the behavior of further consecutive calls. * when(("some arg")) * .thenThrow(new RuntimeException()) * .thenReturn("foo"); * * //Alternative, shorter version for consecutive stubbing: * when(("some arg")) * .thenReturn("one", "two"); * //is the same as: * when(("some arg")) * .thenReturn("one") * .thenReturn("two"); * * //shorter version for consecutive method calls throwing exceptions: * when(("some arg")) * .thenThrow(new RuntimeException(), new NullPointerException(); * * </code></pre> * * For stubbing void methods with throwables see: {@link Mockito#doThrow(Throwable...)} * <p> * Stubbing can be overridden: for example common stubbing can go to fixture * setup but the test methods can override it. * Please note that overridding stubbing is a potential code smell that points out too much stubbing. * <p> * Once stubbed, the method will always return stubbed value regardless * of how many times it is called. * <p> * Last stubbing is more important - when you stubbed the same method with * the same arguments many times. * <p> * Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b>. * Let's say you've stubbed <code>()</code>. * If your code cares what <code>()</code> returns then something else breaks(often before even <code>verify()</code> gets executed). * If your code doesn't care what <code>get(0)</code> returns then it should not be stubbed. * * <p> * See examples in javadoc for {@link Mockito} class * @param methodCall method to be stubbed * @return OngoingStubbing object used to stub fluently. * <strong>Do not</strong> create a reference to this returned object. */ @CheckReturnValue public static <T> OngoingStubbing<T> when(T methodCall) { return MOCKITO_CORE.when(methodCall); }
/** * Sets a return value to be returned when the method is called. : * <pre class="code"><code class="java"> * when(()).thenReturn(10); * </code></pre> * * See examples in javadoc for {@link Mockito#when} * * @param value return value * * @return object that allows stubbing consecutive calls */ OngoingStubbing<T> thenReturn(T value);
/** * Sets consecutive return values to be returned when the method is called. : * <pre class="code"><code class="java"> * when(()).thenReturn(1, 2, 3); * </code></pre> * * Last return value in the sequence (in example: 3) determines the behavior of further consecutive calls. * <p> * See examples in javadoc for {@link Mockito#when} * * @param value first return value * @param values next return values * * @return object that allows stubbing consecutive calls */ // Additional method helps users of JDK7+ to hide heap pollution / unchecked generics array // creation warnings (on call site) @SuppressWarnings({"unchecked", "varargs"}) OngoingStubbing<T> thenReturn(T value, T... values);
验证调用次数:
verify(T mock);
verify(T mock, VerificationMode mode);
@Test void mockitoMethodVerify(){ ArrayList mockList = mock(); //验证方法是否被调用及执行次数 (1); verify(mockList).add(1); (1); (2); verify(mockList,times(2)).add(1); verify(mockList,never()).add(3); verify(mockList,atLeastOnce()).add(1); verify(mockList,atLeast(2)).add(1); verify(mockList,atMostOnce()).add(2); verify(mockList,atMost(2)).add(1); }
@Test void mockitoMethodVerify(){ ArrayList mockList = mock(); //验证方法是否被调用及执行次数 (1); (1); verify(mockList,atLeast(3)).add(1); }
API如下所示:
/** * Verifies certain behavior <b>happened once</b>. * <p> * Alias to <code>verify(mock, times(1))</code> : * <pre class="code"><code class="java"> * verify(mock).someMethod("some arg"); * </code></pre> * Above is equivalent to: * <pre class="code"><code class="java"> * verify(mock, times(1)).someMethod("some arg"); * </code></pre> * <p> * Arguments passed are compared using <code>equals()</code> method. * Read about {@link ArgumentCaptor} or {@link ArgumentMatcher} to find out other ways of matching / asserting arguments passed. * <p> * Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b>. * Let's say you've stubbed <code>()</code>. * If your code cares what <code>()</code> returns then something else breaks(often before even <code>verify()</code> gets executed). * If your code doesn't care what <code>()</code> returns then it should not be stubbed. * * <p> * See examples in javadoc for {@link Mockito} class * * @param mock to be verified * @return mock object itself */ @CheckReturnValue public static <T> T verify(T mock) { return MOCKITO_CORE.verify(mock, times(1)); }
/** * Verifies certain behavior happened at least once / exact number of times / never. : * <pre class="code"><code class="java"> * verify(mock, times(5)).someMethod("was called five times"); * * verify(mock, atLeast(2)).someMethod("was called at least two times"); * * //you can use flexible argument matchers, : * verify(mock, atLeastOnce()).someMethod(<b>anyString()</b>); * </code></pre> * * <b>times(1) is the default</b> and can be omitted * <p> * Arguments passed are compared using <code>equals()</code> method. * Read about {@link ArgumentCaptor} or {@link ArgumentMatcher} to find out other ways of matching / asserting arguments passed. * <p> * * @param mock to be verified * @param mode times(x), atLeastOnce() or never() * * @return mock object itself */ @CheckReturnValue public static <T> T verify(T mock, VerificationMode mode) { return MOCKITO_CORE.verify(mock, mode); }
/** * Allows verifying exact number of invocations. : * <pre class="code"><code class="java"> * verify(mock, times(2)).someMethod("some arg"); * </code></pre> * * See examples in javadoc for {@link Mockito} class * * @param wantedNumberOfInvocations wanted number of invocations * * @return verification mode */ @CheckReturnValue public static VerificationMode times(int wantedNumberOfInvocations) { return (wantedNumberOfInvocations); }
/** * Alias to <code>times(0)</code>, see {@link Mockito#times(int)} * <p> * Verifies that interaction did not happen. : * <pre class="code"><code class="java"> * verify(mock, never()).someMethod(); * </code></pre> * * <p> * If you want to verify there were NO interactions with the mock * check out {@link Mockito#verifyZeroInteractions(Object...)} * or {@link Mockito#verifyNoMoreInteractions(Object...)} * <p> * See examples in javadoc for {@link Mockito} class * * @return verification mode */ @CheckReturnValue public static VerificationMode never() { return times(0); }
/** * Allows at-least-once verification. : * <pre class="code"><code class="java"> * verify(mock, atLeastOnce()).someMethod("some arg"); * </code></pre> * Alias to <code>atLeast(1)</code>. * <p> * See examples in javadoc for {@link Mockito} class * * @return verification mode */ @CheckReturnValue public static VerificationMode atLeastOnce() { return (); }
/** * Allows at-least-x verification. : * <pre class="code"><code class="java"> * verify(mock, atLeast(3)).someMethod("some arg"); * </code></pre> * * See examples in javadoc for {@link Mockito} class * * @param minNumberOfInvocations minimum number of invocations * * @return verification mode */ @CheckReturnValue public static VerificationMode atLeast(int minNumberOfInvocations) { return (minNumberOfInvocations); }
/** * Allows at-most-once verification. : * <pre class="code"><code class="java"> * verify(mock, atMostOnce()).someMethod("some arg"); * </code></pre> * Alias to <code>atMost(1)</code>. * <p> * See examples in javadoc for {@link Mockito} class * * @return verification mode */ @CheckReturnValue public static VerificationMode atMostOnce() { return (); }
/** * Allows at-most-x verification. : * <pre class="code"><code class="java"> * verify(mock, atMost(3)).someMethod("some arg"); * </code></pre> * * See examples in javadoc for {@link Mockito} class * * @param maxNumberOfInvocations max number of invocations * * @return verification mode */ @CheckReturnValue public static VerificationMode atMost(int maxNumberOfInvocations) { return (maxNumberOfInvocations); }
验证失败对应的异常:
异常抛出
when() ...thenThrow(); 当满足条件时候,抛出异常
doThrow()...when(); 满足when中条件时候,抛出异常
当when条件中函数返回值为void时候,不可用thenThrow(),用doThrow()
@Test void mockitoMethodException() { ArrayList mockList = mock(); (1); when((2)).thenThrow(new Exception("异常抛出!")); doThrow(new Exception("异常抛出!")).when(mockList).clear(); }
返回回调接口生成期望值
when(methodCall).thenAnswer(answer));
doAnswer(answer).when(methodCall).[method];
调用真实的方法
doCallRealMethod().when(mock).[method];