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); } }
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
- Refer to Martin Fowler's article on mocks and stubs from http://martinfowler.com/articles/mocksArentStubs.html
- Refer to the xUnit pattern's comparison of test doubles from http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html