
MOCKITO COOKBOOK
By :

Before going into details regarding Mockito and TestNG integration, it is worth mentioning a few words about TestNG.
TestNG is a unit testing framework for Java that was created, as the author defines it on the tool's website (refer to the See also section for the link), out of frustration for some JUnit deficiencies. TestNG was inspired by both JUnit and TestNG and aims at covering the whole scope of testing—from unit, through functional, integration, end-to-end tests, and so on. However, the JUnit library was initially created for unit testing only.
The main differences between JUnit and TestNG are as follows:
@BeforeClass
annotated methods)—that's why in TestNG you don't have to define these methods as static@Before
versus TestNG's @BeforeMethod
Mockito in Version 1.9.5 doesn't provide any out-of-the-box solution to integrate with TestNG in a simple way, but there is a special Mockito subproject for TestNG (refer to the See also section for the URL) that should be part one of the subsequent Mockito releases. In the following recipe, we will take a look at how to profit from that code and that very elegant solution.
When you take a look at Mockito's TestNG subproject on the Mockito GitHub repository, you will find that there are three classes in the org.mockito.testng
package, as follows:
MockitoAfterTestNGMethod
MockitoBeforeTestNGMethod
MockitoTestNGListener
Unfortunately, until this project eventually gets released, you have to just copy and paste those classes to your codebase.
To integrate TestNG and Mockito, perform the following steps:
MockitoAfterTestNGMethod
, MockitoBeforeTestNGMethod
, and MockitoTestNGListener
classes to your codebase from Mockito's TestNG subproject.@Listeners(MockitoTestNGListener.class)
.@Mock
or @Spy
annotation to have either a mock or spy object instantiated.@InjectMocks
annotation to first instantiate the @InjectMock
annotated field and inject all the @Mock
or @Spy
annotated fields into it (if applicable).@Captor
annotation to make Mockito instantiate an argument captor (check Chapter 6, Verifying Test Doubles, for more details).Now let's take a look at this snippet that, using TestNG, checks whether the mean tax factor value has been calculated properly (remember that 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 Hamcrest assertThat(...)
method):
@Listeners(MockitoTestNGListener.class) public class MeanTaxFactorCalculatorTestNgTest { static final double TAX_FACTOR = 10; @Mock TaxService taxService; @InjectMocks MeanTaxFactorCalculator systemUnderTest; @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); } }
TestNG allows you to register custom listeners (your listener class has to implement the IInvokedMethodListener
interface). Once you do this, the logic inside the implemented methods will be executed before and after every configuration, and test methods get called. Mockito provides you with a listener whose responsibilities are as follows:
@Mock
annotation (it is done only once)Remember that with TestNG all mocks are reset (or initialized if it hasn't already been done) before any TestNG method!
@InjectMocks
analysisChange the font size
Change margin width
Change background colour