Verifying that interactions never happened

In this recipe, we will verify the following two cases:

  • A specified method on a mock was never executed
  • The methods on the mock were executed

You might wonder whether there is any reason to check that a method on a mock was never executed. Well, imagine that your company is paying plenty of money for a bank transfer (let's assume that it's done via a web service). Having such business requirements where if some initial conditions were not met the bank transfer should not take place, you can check whether the method was executed.

If you actually need to verify that no more interactions took place on the mock, then perhaps you shouldn't actually have done this (check the link, http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/, for Szczepan Faber's article on that topic). If it's not a business requirement, you should not worry about the unexpected; perhaps, some additional methods of the mock can actually be executed if it doesn't change the way the application works. If you do a TDD, then you won't have this issue since you would write only the piece of code that is really necessary.

Getting ready

Our system under test will be a TaxTransferer class that will transfer tax for a non-null person as follows:

public class TaxTransferer {

    private final TaxService taxService;

    public TaxTransferer(TaxService taxService) {
        this.taxService = taxService;
    }

    public void transferTaxFor(Person person) {
        if (person == null) {
            return;
        }
        taxService.transferTaxFor(person);
    }

}

How to do it...

To verify whether the mock's method was not invoked, call Mockito.verify(mock, VerificationMode.never()).methodToVerify(...).

Let's check the JUnit test that verifies whether the web service's method has been called at most twice (see Chapter 1, Getting Started with Mockito, for the TestNG configuration):

@RunWith(MockitoJUnitRunner.class)
public class TaxTransfererTest {

    @Mock TaxService taxService;

    @InjectMocks TaxTransferer systemUnderTest;

    @Test
    public void should_not_call_web_service_method_if_person_is_null() {
        // when
        systemUnderTest.transferTaxFor(null);

        // then
        verify(taxService, never()).transferTaxFor(any(Person.class));
    }

}

How it works...

Since the never() verification works in the same way as the times(0) verification, please refer to the How it works... section of the Verifying the method invocation count with times() recipe for more details.

There's more...

You can use the Mockito.verifyZeroInteractions(...) method to specify that you do not wish interactions to take place with a mock.

However, it will involve all the existing calls on the mock (even those from the setup phase of your test). So, we could rewrite the aforementioned test in another, less user friendly and readable way; for example, for JUnit, you can use the following code:

@RunWith(MockitoJUnitRunner.class)
public class TaxTransfererTest {

    @Mock TaxService taxService;

    @InjectMocks TaxTransferer systemUnderTest;

    @Test
    public void should_not_interact_with_web_service_in_any_way_if_person_is_null() {
        // when
        systemUnderTest.transferTaxFor(null);

        // then
        verifyZeroInteractions(taxService);
    }
}

You can call either the verifyZeroInteractions(...) or verifyNoMoreInteractions(...) method and get the same result since both do the same task (they call the same methods under the hood).

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.242