SpringBoot项目中单元测试与集成测试的应用

时间:2024-11-11 07:48:37

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];