Mocked Dependency Object Is Null After Using Mockito @InjectMocks Annotation

Let me explain the problem first. We have a Java class under test. We are using Junit with Mockito framework to write the unit test cases.
We have annotated our test class with @InjectMocks annotation as below:

	@InjectMocks
	private TestClass testClass;

	@Mock
	private Dependency1 dependency1;
	
	@Mock
	private Dependency2 dependency2;

That should inject mocked dependencies to the testClass instance. But even after this, when we call a test method like below, we get java.lang.NullPointerException for a mocked dependency. In the below example dependency2 object is null.

    @Test
    public void testAutoVerifyEmailWhenInternalAPICall() {
    	when(dependency2.get(1)).thenReturn(1);
    	testClass.get(1);	
    }

It can happen if you have mixed various dependency injections. It basically means some properties are injected via Constructor injection, some via Property setter injection & others via Field injection.
For example, our actual class under test can look like below:

public Class TestClass{

        private Dependency1 dependency1;
	
	@Inject
	private Dependency2 dependency2;
	
	@Inject
	public TestClass(Dependency1 dependency1){
           this.dependency1 = dependency1;	    
	}
	...
}

It has dependency1 object which is injected via constructor & dependency2 object which is injected via Field injection. Now we need to understand how @InjectMocks annotation works at a high level. @InjectMocks can’t mix different dependency injection types. It will search for & execute only one type of dependency injection (either Constructor injection, Property setter injection or Field injection in the given order). So if Constructor injection is present as in our example, only the dependencies used in Constructor injection will be injected by @InjectMocks (in our case it is dependency1 object). Any other field which was injected via Property Setter or Field injection will have null value.

That’s why we were getting java.lang.NullPointerException for dependency2.get(1) method. It is a Field injection & so dependency2 object was set to null.

Ideally if we have constructor to initialize an object, that constructor should properly take care of initializing all required dependencies. If it is our own class we could have solved the problem using default constructor (removing the Constructor injection) & adding both fields via Field injection.

public Class TestClass{
    
    @Inject
    private Dependency1 dependency1;
	
    @Inject
    private Dependency2 dependency2;
    ...
}

Or we could have initialized both fields via Constructor injection as below:

public Class TestClass{

        private Dependency1 dependency1;
	
	private Dependency2 dependency2;
	
	@Inject
	public TestClass(Dependency1 dependency1, Dependency2 dependency2){
           this.dependency1 = dependency1;
           this.dependency2 = dependency2;		
	}
	...
}

In case, it is a third-party class or we are not allowed to modify the source code of the original test class, we can use below code in our Junit test to inject mocked dependencies properly.

	@InjectMocks
	private TestClass testClass;

	@Mock
	private Dependency1 dependency1;
	
	@Mock
	private Dependency2 dependency2;
	
	@Before
        public void setUp() throws Exception {
          
          MockitoAnnotations.initMocks(this);
    }

MockitoAnnotations.initMocks(this) basically initializes objects annotated with Mockito annotations for the test class. In our example, it is the testClass instance annotated with @InjectMocks. This line will search for any mocked dependencies for testClass instance & inject them properly. It can cover both Constructor injected & Field injected dependencies. So mixing of dependencies from the original test class is handled. In our case, both dependency1 & dependency2 objects should be properly injected now. NullPointerException should be resolved.

2 thoughts on “Mocked Dependency Object Is Null After Using Mockito @InjectMocks Annotation”

  1. How do you inject mocks into inner implementations?

    Let’s consider the following example, I have this test:

    @InjectMocks
    private TestClass testClass;

    @Mock
    private Dependency1 dependency1;

    @Mock
    private Dependency2 dependency2;

    @Before
    public void setUp() throws Exception {

    MockitoAnnotations.initMocks(this);
    }

    However, `testClass` calls another dependency called `anotherDependency` and this dependency it’s the one that uses `dependency1`. The problem I encountered here is that the mock is injected into `testClass`, but if I call `anotherDependency` inside `testClass`, and this `anotherDependency` calls the mock `dependency1`, what I get is the real injection instead of the mock.

    Just to clarify, I don’t want to Mock “anotherDependency” I want to use it for my test.

    Thanks in advance.

    Reply
    • Hi Daniel. I think there is a fundamental misunderstanding. The unit test is supposed to validate the class under test. “anotherDependency” is not the class under test. It is a dependency to the class under test. So it should be either mocked or stubbed out to get the desired value required for the test methods. I do not understand why you don’t want to mock. That shouldn’t be the case unless I missed something.

      Reply

Leave a Comment