Mockito Cookbook
上QQ阅读APP看书,第一时间看更新

Creating mocks in code

Before a mock is interacted with, it needs to be created. Mockito gives you several overloaded versions of the Mockito.mock method. Let's take a look at a few of them:

  • mock(Class<T> classToMock): This method creates a mock of a given class with a default answer set to returning default values (if not overriden by a custom Mockito configuration). When creating mocks in code, you will most likely be using this method.
  • mock(Class<T> classToMock, String name): This method creates a mock of a given class with a default answer set to returning default values. It also sets a name to the mock. This name is present in all verification messages. That's very useful in debugging, since it allows you to distinguish the mocks.
  • mock(Class<T> classToMock, Answer defaultAnswer): This method creates a mock of a given class with a default answer set to the one passed as the method's argument. In other words, all of the nonstubbed mock's method will act as defined in the passed answer.
  • mock(Class<T> classToMock, MockSettings mockSettings): This method creates a mock of a given class with customizable mock settings. You should hardly ever need to use that feature.

Getting ready

In the following code, our system under test is a class that calculates a mean value of tax factors retrieved through a web service:

public class MeanTaxFactorCalculator {

    private final TaxService taxService;

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

    public double calculateMeanTaxFactorFor(Person person) {
        double currentTaxFactor = taxService.getCurrentTaxFactorFor(person);
        double anotherTaxFactor = taxService.getCurrentTaxFactorFor(person);
        return (currentTaxFactor + anotherTaxFactor) / 2;
    }

}

Let's now write a test for the system that will check whether it can properly calculate the mean value of the tax factor. We have to create a stub of TaxService and stub its behavior (we don't want it to send any real requests).

How to do it...

To create a mock of a given class using the Mockito static method, you have to call the static Mockito.mock(Class<T> classToMock) method with the type of class to mock.

The following test is written for JUnit. For the TestNG configuration, refer to Chapter 1, Getting Started with Mockito (I'm using the BDDMockito.given(...) and AssertJ's BDDAssertions.then(...) static methods. Refer to Chapter 7, Verifying Behavior with Object Matchers, on how to work with AssertJ or how to do the same with Hamcrest's assertThat(...)).

public class MeanTaxFactorCalculatorTest {

  static final double TAX_FACTOR = 10;
  
  TaxService taxService = mock(TaxService.class);

  MeanTaxFactorCalculator systemUnderTest = new MeanTaxFactorCalculator(taxService);

  @Test
  public void should_calculate_mean_tax_factor() {
    // given
    given(taxService.getCurrentTaxFactorFor(any(Person.class))).willReturn(TAX_FACTOR);

    // when
    double meanTaxFactor = systemUnderTest.calculateMeanTaxFactorFor(new Person());

    // then
    then(meanTaxFactor).isEqualTo(TAX_FACTOR);
  }
  
}

Note

You can statically import the method to increase readability, as presented in the following example:

import static org.mockito.Mockito.mock;   
TaxService taxService = mock(TaxService.class);

How it works...

Internally, Mockito calls the overloaded mock method that takes the MockSettings argument and executes it with a default answer set to the RETURNS_DEFAULT value (in other words, returns zeroes, empty collections, null values, and so on.) Next, by means of the MockitoCore class, a custom CGLIB proxy is created and returned to the user.

See also