Mockito and Dependency Injection

When writing your Java unit test you will soon need a way to handle the dependencies of your classes under test. Mockito have some nice features that simplify the creation and usage of mock objects that have improved gradually during the last couple of years.

Class under test

Imagine that you write an Example class that has a Delegate dependency. It may be implemented as a POJO with constructor injection:

Alternatively, it could be rewritten using setter injection based on Java EE 6 / JSR 330 annotations:

It could also be a Spring bean based on field injection:

There are more ways to refactor this class, but you get the point.

The Mockito way

It turns out that all these examples can be verified using the same Mockito test:

The interesting part of this test is the code that is not there. You may be surprised to find that the test does not contain the traditional boilerplate code associated with jUnit tests such as a @Before method, there is no new Example() call that instantiates the class under test, nor any application context from which an example bean can be obtained. Moreover, there is no call to the mock() method to create the delegate mock object. Despite all this, an Example instance will be created, a mock object will be injected into it, and the test will execute and pass.

When the MockitoJUnitRunner executes the test, Mockito creates mocks and spies instances for all fields that are annotated with the @Mock or the @Spy annotations. Next, the field declaration that is annotated with the @InjectMocks annotation is instantiated and Mockito injects the mocks and spies into it. This occurs before each test method, so there is no there is no residual state left from any previous test that may affect the current test. From this part onwards, the test behaves like any other test and you can write your assertions and verifications as usual.

As can be seen from the above examples, Mockito supports dependency injection by using constructor arguments, setter methods and field injection. The underlying implementation relies on reflection, which means that there is no dependency on the Java EE 6 or Spring annotations as far as Mockito is concerned (obviously, you will get a compile error if you do not add the corresponding dependencies to the class path and your application will fail if there is no matching bean definition in runtime, but that has nothing to do with the unit test).

Limitations

There are some things you should be aware of when you are writing test this kind of test, such as

  • The order of which the dependency injection is attempted is constructor injection, setter injection and lastly field injection.
  • Only one dependency injection strategy will occur for each test case. For example, if a suitable constructor is found, neither the setter injection nor the field injection will come to play.
  • Mockito does not report if any dependency injection strategy fails.
  • For constructor injection the “biggest” constructor is chosen, and null will be passed as argument for dependencies that are neither mocks nor spies.
  • Fields may not be declared as final or static (but private fields are supported).

Please read the documentation of the @InjectMocks to learn about the details.

Dependency

Mockito 1.9.0

References

Mattias Severson

Mattias is a senior software engineer specialized in backend architecture and development with experience of cloud based applications and scalable solutions. He is a clean code proponent who appreciates Agile methodologies and pragmatic Test Driven Development. Mattias has experience from many different environments, including everything between big international projects that last for years and solo, single day jobs. He is open-minded and curious about new technologies. Mattias believes in continuous improvement on a personal level as well as in the projects that he is working on. Additionally, Mattias is a frequent speaker at user groups, companies and conferences.

This Post Has 11 Comments

  1. kbird

    Thanks good post!

  2. ktulinho

    Thanks, this is exactly what I was looking for!

  3. Heinz

    Hi,

    thanks for the good post.

    The Needle Framework (http://needle.spree.de) allows simple testing of Java EE component, such as CDI or EJB. Needle analyze the dependencies and injects automatic mock objects. It is well integrated with Mockito and EasyMock.

    Regards, Heinz

    1. Mattias Severson

      Thanks for the tip, I did not know about Needle before.

      Cheers, Mattias

  4. Theresa Stewart

    I have figured it out. It was solved by understanding the order of injection and also which MyClass should be instantiated by the JUnit test.

    Thank you very much, though, for this example. It very much helped!

    Theresa

    1. Mattias Severson

      @Theresa: Good that you solved your problem and that you found my blog post helpful!

  5. Sandeep Asokan

    Super helpful! Thank you for the post.

Leave a Reply