Tutorial

Mockito @InjectMocks - Mocks Dependency Injection

Published on August 3, 2022
Default avatar

By Pankaj

Mockito @InjectMocks - Mocks Dependency Injection

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Mockito @InjectMocks annotations allow us to inject mocked dependencies in the annotated class mocked object. This is useful when we have external dependencies in the class we want to mock. We can specify the mock objects to be injected using @Mock or @Spy annotations.

Mockito @InjectMocks

Mockito tries to inject mocked dependencies using one of the three approaches, in the specified order.

  1. Constructor Based Injection - when there is a constructor defined for the class, Mockito tries to inject dependencies using the biggest constructor.
  2. Setter Methods Based - when there are no constructors defined, Mockito tries to inject dependencies using setter methods.
  3. Field Based - if there are no constructors or field-based injection possible, then mockito tries to inject dependencies into the field itself.

If there is only one matching mock object, then mockito will inject that into the object. If there is more than one mocked object of the same class, then mock object name is used to inject the dependencies.

Mock @InjectMocks Example

Let’s create some services and classes with dependencies so that we can see Mockito dependency injection of mocks in action. Service Classes

package com.journaldev.injectmocksservices;

public interface Service {

	public boolean send(String msg);
}
package com.journaldev.injectmocksservices;

public class EmailService implements Service {

	@Override
	public boolean send(String msg) {
		System.out.println("Sending email");
		return true;
	}

}
package com.journaldev.injectmocksservices;

public class SMSService implements Service {

	@Override
	public boolean send(String msg) {
		System.out.println("Sending SMS");
		return true;
	}
}

App Service Classes with Dependencies

package com.journaldev.injectmocksservices;

//For Constructor Based @InjectMocks injection
public class AppServices {

	private EmailService emailService;
	private SMSService smsService;

	public AppServices(EmailService emailService, SMSService smsService) {
		this.emailService = emailService;
		this.smsService = smsService;
	}

	public boolean sendSMS(String msg) {
		return smsService.send(msg);
	}

	public boolean sendEmail(String msg) {
		return emailService.send(msg);
	}
}
package com.journaldev.injectmocksservices;

//For Property Setter Based @InjectMocks injection
public class AppServices1 {

	private EmailService emailService;
	private SMSService smsService;

	public void setEmailService(EmailService emailService) {
		this.emailService = emailService;
	}

	public void setSmsService(SMSService smsService) {
		this.smsService = smsService;
	}

	public boolean sendSMS(String msg) {
		return smsService.send(msg);
	}

	public boolean sendEmail(String msg) {
		return emailService.send(msg);
	}

}
package com.journaldev.injectmocksservices;

//For Field Based @InjectMocks injection
public class AppServices2 {

	private EmailService emailService;
	private SMSService smsService;

	public boolean sendSMS(String msg) {
		return smsService.send(msg);
	}

	public boolean sendEmail(String msg) {
		return emailService.send(msg);
	}

}

@InjectMocks Constructor Injection Example

package com.journaldev.mockito.injectmocks;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import com.journaldev.injectmocksservices.AppServices;
import com.journaldev.injectmocksservices.AppServices1;
import com.journaldev.injectmocksservices.AppServices2;
import com.journaldev.injectmocksservices.EmailService;
import com.journaldev.injectmocksservices.SMSService;

class MockitoInjectMocksExamples extends BaseTestCase {

	@Mock EmailService emailService;
	
	@Mock SMSService smsService;
	
	@InjectMocks AppServices appServicesConstructorInjectionMock;
	
	@InjectMocks AppServices1 appServicesSetterInjectionMock;
	
	@InjectMocks AppServices2 appServicesFieldInjectionMock;
	
	@Test
	void test_constructor_injection_mock() {
		when(appServicesConstructorInjectionMock.sendEmail("Email")).thenReturn(true);
		when(appServicesConstructorInjectionMock.sendSMS(anyString())).thenReturn(true);
		
		assertTrue(appServicesConstructorInjectionMock.sendEmail("Email"));
		assertFalse(appServicesConstructorInjectionMock.sendEmail("Unstubbed Email"));
		
		assertTrue(appServicesConstructorInjectionMock.sendSMS("SMS"));
		
	}
}

Did you noticed that my test class is extending BaseTestCase. This is to initialize Mockito mocks before the tests, here is the code of the class.

package com.journaldev.mockito.injectmocks;

import org.junit.jupiter.api.BeforeEach;
import org.mockito.MockitoAnnotations;

class BaseTestCase {

	@BeforeEach
	void init_mocks() {
		MockitoAnnotations.initMocks(this);
	}

}

If you won’t call MockitoAnnotations.initMocks(this); then you will get NullPointerException. Also, I am using JUnit 5 to run the test cases. If you are not familiar with it, have a look at JUnit 5 Tutorial.

@InjectMocks Setter Methods Injection Example

@Test
void test_setter_injection_mock() {
	when(appServicesSetterInjectionMock.sendEmail("New Email")).thenReturn(true);
	when(appServicesSetterInjectionMock.sendSMS(anyString())).thenReturn(true);
	
	assertTrue(appServicesSetterInjectionMock.sendEmail("New Email"));
	assertFalse(appServicesSetterInjectionMock.sendEmail("Unstubbed Email"));
	
	assertTrue(appServicesSetterInjectionMock.sendSMS("SMS"));
	
}

@InjectMocks Field Based Injection Example

@Test
void test_field_injection_mock() {
	when(appServicesFieldInjectionMock.sendEmail(anyString())).thenReturn(true);
	when(appServicesFieldInjectionMock.sendSMS(anyString())).thenReturn(true);
	
	assertTrue(appServicesFieldInjectionMock.sendEmail("Email"));
	assertTrue(appServicesFieldInjectionMock.sendEmail("New Email"));
	
	assertTrue(appServicesFieldInjectionMock.sendSMS("SMS"));
	
}

You can check out complete code and more Mockito examples from our GitHub Repository.

Reference: API Doc

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
March 2, 2022

The sample looks confuse… mocking the class you try to test… what are you testing then? your class? no… Mockito maybe?

- Domingo Berrón

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    September 29, 2020

    Why are you writing when(appServicesFieldInjectionMock.sendEmail(anyString())).thenReturn(true); ??? It should be when(emailService.send(anyString()) … Otherwise what is the purpose of @Mock annotated objects here.

    - stupid

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      September 22, 2020

      Mockito now has a JUnit5 extension to avoid having to call explicitly to initMocks(). Just adding @ExtendWith(MockitoExtension.class) At the top of the class, equivalent to the JUnit4’s @RunWith(… Dependency is: org.mockito mockito-junit-jupiter 3.5.11 test Please update the post, thanks.

      - brujua

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        August 3, 2020

        where did you mock the Constructor with Arguments ???

        - Bhargava Surimenu

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          December 16, 2019

          We should not mock the testing classes, eg: AppServices

          - Siva R

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            March 20, 2019

            no source code displayed

            - tester

              Try DigitalOcean for free

              Click below to sign up and get $200 of credit to try our products over 60 days!

              Sign up

              Join the Tech Talk
              Success! Thank you! Please check your email for further details.

              Please complete your information!

              Get our biweekly newsletter

              Sign up for Infrastructure as a Newsletter.

              Hollie's Hub for Good

              Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

              Become a contributor

              Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

              Welcome to the developer cloud

              DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

              Learn more
              DigitalOcean Cloud Control Panel