[java] Initialising mock objects - MockIto

There are many ways to initialize a mock object using MockIto. What is best way among these ?

1.

 public class SampleBaseTestCase {

   @Before public void initMocks() {
       MockitoAnnotations.initMocks(this);
   }
@RunWith(MockitoJUnitRunner.class)
mock(XXX.class);

suggest me if there are any other ways better than these...

This question is related to java junit mockito

The answer is


For the mocks initialization, using the runner or the MockitoAnnotations.initMocks are strictly equivalent solutions. From the javadoc of the MockitoJUnitRunner :

JUnit 4.5 runner initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.


The first solution (with the MockitoAnnotations.initMocks) could be used when you have already configured a specific runner (SpringJUnit4ClassRunner for example) on your test case.

The second solution (with the MockitoJUnitRunner) is the more classic and my favorite. The code is simpler. Using a runner provides the great advantage of automatic validation of framework usage (described by @David Wallace in this answer).

Both solutions allows to share the mocks (and spies) between the test methods. Coupled with the @InjectMocks, they allow to write unit tests very quickly. The boilerplate mocking code is reduced, the tests are easier to read. For example:

@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {

    @Mock private ArticleCalculator calculator;
    @Mock(name = "database") private ArticleDatabase dbMock;
    @Spy private UserProvider userProvider = new ConsumerUserProvider();

    @InjectMocks private ArticleManager manager;

    @Test public void shouldDoSomething() {
        manager.initiateArticle();
        verify(database).addListener(any(ArticleListener.class));
    }

    @Test public void shouldDoSomethingElse() {
        manager.finishArticle();
        verify(database).removeListener(any(ArticleListener.class));
    }
}

Pros: The code is minimal

Cons: Black magic. IMO it is mainly due to the @InjectMocks annotation. With this annotation "you loose the pain of code" (see the great comments of @Brice)


The third solution is to create your mock on each test method. It allow as explained by @mlk in its answer to have "self contained test".

public class ArticleManagerTest {

    @Test public void shouldDoSomething() {
        // given
        ArticleCalculator calculator = mock(ArticleCalculator.class);
        ArticleDatabase database = mock(ArticleDatabase.class);
        UserProvider userProvider = spy(new ConsumerUserProvider());
        ArticleManager manager = new ArticleManager(calculator, 
                                                    userProvider, 
                                                    database);

        // when 
        manager.initiateArticle();

        // then 
        verify(database).addListener(any(ArticleListener.class));
    }

    @Test public void shouldDoSomethingElse() {
        // given
        ArticleCalculator calculator = mock(ArticleCalculator.class);
        ArticleDatabase database = mock(ArticleDatabase.class);
        UserProvider userProvider = spy(new ConsumerUserProvider());
        ArticleManager manager = new ArticleManager(calculator, 
                                                    userProvider, 
                                                    database);

        // when 
        manager.finishArticle();

        // then
        verify(database).removeListener(any(ArticleListener.class));
    }
}

Pros: You clearly demonstrate how your api works (BDD...)

Cons: there is more boilerplate code. (The mocks creation)


My recommandation is a compromise. Use the @Mock annotation with the @RunWith(MockitoJUnitRunner.class), but do not use the @InjectMocks :

@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {

    @Mock private ArticleCalculator calculator;
    @Mock private ArticleDatabase database;
    @Spy private UserProvider userProvider = new ConsumerUserProvider();

    @Test public void shouldDoSomething() {
        // given
        ArticleManager manager = new ArticleManager(calculator, 
                                                    userProvider, 
                                                    database);

        // when 
        manager.initiateArticle();

        // then 
        verify(database).addListener(any(ArticleListener.class));
    }

    @Test public void shouldDoSomethingElse() {
        // given
        ArticleManager manager = new ArticleManager(calculator, 
                                                    userProvider, 
                                                    database);

        // when 
        manager.finishArticle();

        // then 
        verify(database).removeListener(any(ArticleListener.class));
    }
}

Pros: You clearly demonstrate how your api works (How my ArticleManager is instantiated). No boilerplate code.

Cons: The test is not self contained, less pain of code


MockitoAnnotations & the runner have been well discussed above, so I'm going to throw in my tuppence for the unloved:

XXX mockedXxx = mock(XXX.class);

I use this because I find it a little bit more descriptive and I prefer (not out right ban) unit tests not to use member variables as I like my tests to be (as much as they can be) self contained.


There is now (as of v1.10.7) a fourth way to instantiate mocks, which is using a JUnit4 rule called MockitoRule.

@RunWith(JUnit4.class)   // or a different runner of your choice
public class YourTest
  @Rule public MockitoRule rule = MockitoJUnit.rule();
  @Mock public YourMock yourMock;

  @Test public void yourTestMethod() { /* ... */ }
}

JUnit looks for subclasses of TestRule annotated with @Rule, and uses them to wrap the test Statements that the Runner provides. The upshot of this is that you can extract @Before methods, @After methods, and even try...catch wrappers into rules. You can even interact with these from within your test, the way that ExpectedException does.

MockitoRule behaves almost exactly like MockitoJUnitRunner, except that you can use any other runner, such as Parameterized (which allows your test constructors to take arguments so your tests can be run multiple times), or Robolectric's test runner (so its classloader can provide Java replacements for Android native classes). This makes it strictly more flexible to use in recent JUnit and Mockito versions.

In summary:

  • Mockito.mock(): Direct invocation with no annotation support or usage validation.
  • MockitoAnnotations.initMocks(this): Annotation support, no usage validation.
  • MockitoJUnitRunner: Annotation support and usage validation, but you must use that runner.
  • MockitoRule: Annotation support and usage validation with any JUnit runner.

See also: How JUnit @Rule works?


There is a neat way of doing this.

  • If it's an Unit Test you can do this:

    @RunWith(MockitoJUnitRunner.class)
    public class MyUnitTest {
    
        @Mock
        private MyFirstMock myFirstMock;
    
        @Mock
        private MySecondMock mySecondMock;
    
        @Spy
        private MySpiedClass mySpiedClass = new MySpiedClass();
    
        // It's gonna inject the 2 mocks and the spied object per reflection to this object
        // The java doc of @InjectMocks explains it really well how and when it does the injection
        @InjectMocks
        private MyClassToTest myClassToTest;
    
        @Test
        public void testSomething() {
        }
    }
    
  • EDIT: If it's an Integration test you can do this(not intended to be used that way with Spring. Just showcase that you can initialize mocks with diferent Runners):

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("aplicationContext.xml")
    public class MyIntegrationTest {
    
        @Mock
        private MyFirstMock myFirstMock;
    
        @Mock
        private MySecondMock mySecondMock;
    
        @Spy
        private MySpiedClass mySpiedClass = new MySpiedClass();
    
        // It's gonna inject the 2 mocks and the spied object per reflection to this object
        // The java doc of @InjectMocks explains it really well how and when it does the injection
        @InjectMocks
        private MyClassToTest myClassToTest;
    
        @Before
        public void setUp() throws Exception {
              MockitoAnnotations.initMocks(this);
        }
    
        @Test
        public void testSomething() {
        }
    }
    

A little example for JUnit 5 Jupiter, the "RunWith" was removed you now need to use the Extensions using the "@ExtendWith" Annotation.

@ExtendWith(MockitoExtension.class)
class FooTest {

  @InjectMocks
  ClassUnderTest test = new ClassUnderTest();

  @Spy
  SomeInject bla = new SomeInject();
}

The other answers are great and contain more detail if you want/need them.
In addition to those, I would like to add a TL;DR:

  1. Prefer to use
    • @RunWith(MockitoJUnitRunner.class)
  2. If you cannot (because you already use a different runner), prefer to use
    • @Rule public MockitoRule rule = MockitoJUnit.rule();
  3. Similar to (2), but you should not use this anymore:
    • @Before public void initMocks() { MockitoAnnotations.initMocks(this); }
  4. If you want to use a mock in just one of the tests and don't want to expose it to other tests in the same test class, use
    • X x = mock(X.class)

(1) and (2) and (3) are mutually exclusive.
(4) can be used in combination with the others.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to junit

Eclipse No tests found using JUnit 5 caused by NoClassDefFoundError for LauncherFactory How to resolve Unneccessary Stubbing exception JUnit 5: How to assert an exception is thrown? How do I mock a REST template exchange? Class Not Found: Empty Test Suite in IntelliJ Unable to find a @SpringBootConfiguration when doing a JpaTest Failed to load ApplicationContext (with annotation) Example of Mockito's argumentCaptor Mockito - NullpointerException when stubbing Method Spring jUnit Testing properties file

Examples related to mockito

How to resolve Unneccessary Stubbing exception How do I mock a REST template exchange? Mockito : doAnswer Vs thenReturn Example of Mockito's argumentCaptor Mockito: Mock private field initialization Mockito - NullpointerException when stubbing Method Usages of doThrow() doAnswer() doNothing() and doReturn() in mockito Java verify void method calls n times with Mockito Unfinished Stubbing Detected in Mockito How do I mock an autowired @Value field in Spring with Mockito?