Stubbing void methods

In this recipe, we will stub a void method. A void method is one that doesn't return a value. Remember that since we want to partially stub a mock, it most likely means that our class is doing too much, and that is quite true for this scenario. It is best practice to not write such code – always try to follow the SOLID principles.

Getting ready

For this recipe, our system under test will be the PersonDataUpdator class, which delegates most of the work to its collaborator, TaxFactorService. The latter calculates the mean value of the tax factor (for simplicity, it's a fixed value) and then updates the person's tax data via a web service (since it's a simple example, we do not have any real web service calls):

public class PersonDataUpdator {

  private final TaxFactorService taxFactorService;

  public PersonDataUpdator(TaxFactorService taxFactorService) {
    this.taxFactorService = taxFactorService;
  }

  public boolean processTaxDataFor(Person person) {
    try {
      double meanTaxFactor = taxFactorService.calculateMeanTaxFactor();
      taxFactorService.updateMeanTaxFactor(person, meanTaxFactor);
      return true;
    } catch (ConnectException exception) {
      System.err.printf("Exception occurred while trying update person data [%s]%n", exception);
      throw new TaxFactorConnectionException(exception);
    }
  }

}

The TaxFactorService class is shown in the following code (note that updateMeanTaxFactor is throwing a checked exception, ConnectException):

public class TaxFactorService {

    private static final double MEAN_TAX_FACTOR = 0.5;

    public void updateMeanTaxFactor(Person person, double meanTaxFactor) throws ConnectException {
      System.out.printf("Updating mean tax factor [%s] for person with defined country%n", meanTaxFactor);
    }

    public double calculateMeanTaxFactor() {
      return MEAN_TAX_FACTOR;
    }

}

How to do it...

To stub a spy's void method in such a way that it does nothing, you have to perform the following steps:

  1. For the BDD approach, call the BDDMockito.willDoNothing().given(spy).methodToStub(). Or, in the standard manner, call Mockito.doNothing().when(spy).methodToStub().
  2. Whichever approach you've chosen, willDoNothing() or doNothing(), you will pass the spy itself in the given(...) or when(...) method.
  3. Remember that the exception that was passed last during stubbing will be thrown for each stubbed method call. Have a look at the following code:
    willDoNothing().willThrow(exception).given(taxFetcher).getTax();

    As shown in the preceding code, regardless of the number of taxFetcher.getTax() method executions, the method will first do nothing and then always throw an exception (until stubbed again).

The following snippet depicts the aforementioned scenario for JUnit. See Chapter 1, Getting Started with Mockito, for the TestNG configuration (I'm using the BDDMockito.given(...) and AssertJ's BDDAssertions.then(...) static methods. Check out Chapter 7, Verifying Behavior with Object Matchers, on how to work with AssertJ or how to do the same with Hamcrest's assertThat(...)). Have a look at the following snippet:

@RunWith(MockitoJUnitRunner.class)
public class PersonDataUpdatorTest {

    @Spy TaxFactorService taxFactorService;

    @InjectMocks PersonDataUpdator systemUnderTest;

    @Test
    public void should_successfully_update_tax_factor_for_person() throws ConnectException {
        // given
        willDoNothing().given(taxFactorService).updateMeanTaxFactor(any(Person.class), anyDouble());

        // when
        boolean success = systemUnderTest.processTaxDataFor(new Person());
      
      // then
      then(success).isTrue();
    }
  
}

How it works...

A spy is a special case of a mock. Refer to the Stubbing void methods recipe of Chapter 4, Stubbing Behavior of Mocks, for more information.

There's more...

Say you want to make a method first throw an exception and do that only once; after that, you want the method to do nothing. Take a look at the following snippet, which shows how to achieve this:

willThrow(exception).willNothing().given(spy).methodToSpy();

See also

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

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