Using Mockito with TestNG

There is a difference in the behaviour of these frameworks:

  • JUnit creates a new instance of class for every of its test methods. This means that the fields are not shared between tests.
  • But TestNG creates only one object and thus the state in fields is shared between to @Tests

For Mockito you need to init mocks before every test method so that the state is not shared between two @Tests in TestNG:

@BeforeMethod
public void init() {
    MockitoAnnotations.initMocks(this);
}

For JUnit it works out of box because 2nd @Test has its own fields and its own mocks.


I'm not sure, if this answer fits to the questioners problem, because the mocks are not listed. But I'd like to re-state one comment from andy in the accepted answer, which helped me out on the same problem. Here are some more details and an example:


public class B {

private A a;

B (A a) {
    this.a = a
}

// ...

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;


public class MyTest {

    @Mock
    A a;

    @InjectMocks
    B B;

    @BeforeMethod
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void test1() {
        // ...
        // b.toString();
        // b.getA().toString();
        // a.toString();
    }

    @Test
    void test2() {
        // ...
        // b.toString();
        // b.getA().toString();
        // a.toString();
    }

    @AfterMethod
    public void reset()
    {
        // Solution:
        b = null;
    }
}

Mockitos MockitoAnnotations.initMocks(this) only re-initializes mocks, as Mockito.reset(a) only resets mocks. The problem is the class under test, which is annotated with @InjectMocks. This class, here named B, is not initialized again. It is initialized for the first test with a mock of A, the mock of A is re-initialized but B still contains the first version of A.

The solution is to reset the class under test manually with b = null at any plausible place (@AfterMethod or before initMocks). Then Mockito also re-inizialized the class under test B.


You can also use MockitoTestNGListener it is similar to JUnit MockitoJUnitRunner or MockitoExtension.

Example of code:

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.util.Map;

@Listeners(MockitoTestNGListener.class)
public class MyTest {

    @Mock
    Map map;

    @InjectMocks
    SomeType someType;

    @Test
    void test() {
        // ...
    }
}