Mockito part 3: Verification of results

Zero: Prepare the code

public class Foo {

    private Bar bar;
    private Tou tou;

    public int sum(int a, int b) {
        return bar.add(a, b);
    }

    public int count(a) {
        bar.badCode();
        return 5; }}public class Bar {

    public int add(int a, int b) {
        return a + b;
    }

    public void badCode(a) {
        throw new RuntimeException("bad bar code"); }}public class Tou {

    public void tou(a) {
        throw new RuntimeException("tou"); }}Copy the code

One: whether the method is called/the number of times the method is called

  • atLeast(int minNumberOfInvocations)Allow validation for at least X calls.
  • atLeastOnce()Allows validation of at least one invocation.
  • atMost(int maxNumberOfInvocations)Allows validation up to X calls.
  • atMostOnce()Validation for up to one invocation is allowed.
  • never() times(0)Alias, seetimes(int)
  • only()Allows you to check if a given method is called only once.
  • times(int wantedNumberOfInvocations)Allows you to verify the exact number of calls.
  • verify(T mock)Validate some behaviorIt happened once.
  • verify(T mock, VerificationMode mode)Verify that some behavior occurred at least once/exactly how many times/never occurred.
  • verifyNoInteractions(Object... mocks)Verify that no interaction has occurred on the given mock object.
  • verifyNoMoreInteractions(Object... mocks)Check for any unvalidated interactions on any given mock object.
  • validateMockitoUsage()Verify that there are no writing errors in the test code.

Example:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    // Member variables inside foo are automatically injected into objects generated by the @mock annotation.
    @InjectMocks
    private Foo foo;

    // The bar object is automatically injected into the @injectMocks object's member variables.
    @Mock(lenient = true)
    private Bar bar;

    // The tou object is automatically injected into the @injectMocks object's member variables.
    @Mock(lenient = true)
    private Tou tou;

    @Test
    public void doReturnTest(a) {
        Mockito.doReturn(7).when(bar).add(1.2);

        foo.sum(1.2);

        //1: Verify that the bar.add(1,2) method is called once.
        Mockito.verify(bar).add(1.2);
        //2: equal to 1.
        Mockito.verify(bar, Mockito.times(1)).add(1.2);
        //3: verify that the bar.add(1,2) method has been called at least n times.
        Mockito.verify(bar, Mockito.atLeast(1)).add(1.2);
        //4: verify that the bar.add(1,2) method has been called at least once.
        Mockito.verify(bar, Mockito.atLeastOnce()).add(1.2);
        //5: verify that the bar.add(1,2) method is called at most n times.
        Mockito.verify(bar, Mockito.atMost(1)).add(1.2);
        //6: verify that the bar.add(1,2) method is called at most once.
        Mockito.verify(bar, Mockito.atMostOnce()).add(1.2);
        //7: Verify that the bar.badcode () method is never called.
        Mockito.verify(bar, Mockito.never()).badCode();
        //8: verify that the bar.add(1,2) method is called only once.
        Mockito.verify(bar, Mockito.only()).add(1.2);
        //9: Verify that no interaction has occurred on the given mock object.
        Mockito.verifyNoInteractions(tou);
        //10: Checks for any unvalidated interactions on any given mock object. (The interaction between the test execution and the BAR object has been verified, and the verification has passed)
        Mockito.verifyNoMoreInteractions(bar);
        //11: Verify that there are no writing errors in the test code.Mockito.validateMockitoUsage(); }}Copy the code

Two: method execution time verification

  • after(long millis)Validation is triggered after a given number of milliseconds, allowing testing of asynchronous code.
  • timeout(long millis)Validation is triggered over and over again, up to a given number of milliseconds, allowing testing of asynchronous code.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    // Member variables inside foo are automatically injected into objects generated by the @mock annotation.
    @InjectMocks
    private Foo foo;

    // The bar object is automatically injected into the @injectMocks object's member variables.
    @Mock(lenient = true)
    private Bar bar;

    // The tou object is automatically injected into the @injectMocks object's member variables.
    @Mock(lenient = true)
    private Tou tou;

    @Test
    public void doReturnTest(a) {
        Mockito.doReturn(7).when(bar).add(1.2);

        foo.sum(1.2);

        //1: verify that the bar.add(1,2) method is executed within 100ms. Validation is triggered after a given number of milliseconds, allowing testing of asynchronous code.
        Mockito.verify(bar, Mockito.after(100)).add(1.2);
        //2: verify that the bar.add(1,2) method is executed within 100ms. Validation is triggered over and over again, up to a given number of milliseconds, allowing testing of asynchronous code.
        Mockito.verify(bar, Mockito.timeout(100)).add(1.2); }}Copy the code

More on the timeout() method:

Validation is triggered over and over again, up to a given number of milliseconds, allowing testing of asynchronous code. Useful when the interaction with a mock object has not yet occurred. The widespread use of the timeout() method can be a code smell — there are better ways to test concurrent code.

See also after(long) for testing asynchronous code. The difference between timeout() and after is in the Javadoc for After (Long).

   Somemethod () is passed when the execution time of somemethod is less than 100 milliseconds
   Exit immediately when validation is satisfied (for example, it may not wait 100 milliseconds)
   verify(mock, timeout(100)).someMethod();
   // The above code can also be written like this:
   verify(mock, timeout(100).times(1)).someMethod();

   // someMethod() passes as long as the time between two calls is less than 100 ms
   verify(mock, timeout(100).times(2)).someMethod();

   // Equivalent to the code above:
   verify(mock, timeout(100).atLeast(2)).someMethod();
 
Copy the code

More on the after(long) method:

Validation is triggered after a given number of milliseconds, allowing testing of asynchronous code. Useful when the interaction with a mock object has not yet occurred. The widespread use of the after() method can be a code smell — there are better ways to test concurrent code.

Not yet implemented for use with InOrder validation.

See also how timeout(Long) tests asynchronous code. The difference between timeout() and after() is explained below.

   // After 100 ms, somemethod() succeeds
   verify(mock, after(100)).someMethod();
   // The above code can also be written like this:
   verify(mock, after(100).times(1)).someMethod();

   // After 100 ms, somemethod() is executed twice
   verify(mock, after(100).times(2)).someMethod();

   // After 100 milliseconds, if someMethod() is not executed, the validation succeeds
   verify(mock, after(100).never()).someMethod();

   // Verify the execution of the someMethod() method in 100ms with the given validation mode,
   // This is useful when using your own custom validation mode.
   verify(mock, new After(100, yourOwnVerificationMode)).someMethod();
 
Copy the code

The timeout () and after ()

  • Timeout () Exits immediately after the authentication succeeds
  • After () waits for the full time to check whether validation has passed

Example:

   / / 1.
   mock.foo();
   verify(mock, after(1000)).foo();
   // Wait 1000 ms for validation to succeed

   / / 2.
   mock.foo();
   verify(mock, timeout(1000)).foo();
   // Immediate success
Copy the code

Three: method call order verification

  • inOrder(Object... mocks)createInOrderObject to allow validation of mock objects in order.
  • calls(int wantedNumberOfInvocations)Allows sequential validation of non-greedy calls.

About inOrder:

Create an InOrder object to allow the simulated objects to be validated sequentially.

   InOrder inOrder = inOrder(firstMock, secondMock);

   inOrder.verify(firstMock).add("was called first");
   inOrder.verify(secondMock).add("was called second");
 
Copy the code

Sequential validation is flexible – you don’t have to validate all interactions one by one, but only those interactions you are interested in sequentially.

In addition, you can create InOrder objects that pass only mock objects related to ordered validation.

InOrder validation is “greedy,” but you’ll barely notice it. If you want to learn more, please read this wiki page.

Starting with Mockito 1.8.4, you can use verifyNoMoreInteractions() in a sequentially sensitive manner. Read more: InOrder verifyNoMoreInteractions ().

About calls () :

Sequential non-greedy validation is allowed. For example,

   inOrder.verify( mock, calls( 2 )).someMethod( "some arg" );
Copy the code
  • If the method is called three times, it will not fail, unlike times(2)
  • Unlike atLeast(2), the third call is not marked as validated

This authentication mode can only be used for sequential authentication.

Four: verification method reference

Modifiers and types Methods and Instructions
static VerificationAfterDelay after(long millis)Validation is triggered after a given number of milliseconds, allowing testing of asynchronous code.
static VerificationMode atLeast(int minNumberOfInvocations)Allow validation of at least X calls.
static VerificationMode atLeastOnce()Allows validation of at least one invocation.
static VerificationMode atMost(int maxNumberOfInvocations)Allows validation up to X calls.
static VerificationMode atMostOnce()Validation for up to one invocation is allowed.
static VerificationMode calls(int wantedNumberOfInvocations)Allows sequential validation of non-greedy calls.
static Object[] ignoreStubs(Object... mocks)For validation, ignore the stub method of the given mock.
static InOrder inOrder(Object... mocks)createInOrderObject that allows you to mock out in sequence.
static LenientStubber lenient()Loose stub, bypassing “strict stub” validation (see Resources)Strictness.STRICT_STUBS).
static VerificationMode never() times(0)Alias, seetimes(int)
static VerificationMode only()Allows you to check if a given method is called only once.
static <T> void reset(T... mocks)Smart Mockito users rarely use this feature because they know it could be a sign of poor testing.
static VerificationWithTimeout timeout(long millis)Validation is triggered over and over again, up to a given number of milliseconds, allowing testing of asynchronous code.
static VerificationMode times(int wantedNumberOfInvocations)Allows you to verify the exact number of calls.
static void validateMockitoUsage()First, if you have any questions, I encourage you to read the Mockito FAQ:Github.com/mockito/moc…
static <T> T verify(T mock)Validate some behaviorIt happened once.
static <T> T verify(T mock, VerificationMode mode)Verify that some behavior occurred at least once/exactly how many times/never occurred.
static void verifyNoInteractions(Object... mocks)Verify that no interaction occurs on a given simulation.
static void verifyNoMoreInteractions(Object... mocks)Checks for any unvalidated interactions with any given simulation.