Mockito @Mock vs @InjectMocks Annotations

During unit testing with junit and mockito, generally, we use @Mock and @InjectMocks annotations to create mocks and SUT (System Under Test) to be tested. In this tutorial, we will learn the difference between @Mock and @InjectMocks annotations in mockito.

1. What is a Mock?

It is important to understand the difference between a mock and an object. An object is an actual instance of a class and any method invoked using object reference will execute the method body defined in the class file.

A mock object is a proxy interface to hide an underlying dependency with cannot be tested in a test environment e.g. database, network locations etc. A method invoked using mocked reference does not execute the actual method body defined in the class file, rather the method behavior is configured using when(...).thenReturn(...) methods.

  • In a junit test, we create objects for the class which need to be tested and its methods to be invoked.
  • We create mocks for the dependencies which will not be present in the test environment and objects are dependent on it to complete the method call.

2. Difference between @Mock and @InjectMocks

In mockito-based junit tests, @Mock annotation creates mocks and @InjectMocks creates actual objects and injects mocked dependencies into it.

  • Use @InjectMocks to create class instances that need to be tested in the test class. We call it ‘code under test‘ or ‘system under test‘.
  • Use @InjectMocks when actual method body needs to be executed for a given class.
  • Use @InjectMocks when we need all or few internal dependencies initialized with mock objects to work method correctly.
  • Use @Mock to create mocks that are needed to support the testing of SUT.
  • We must define the when(...).thenReturn(...) methods for mock objects whose class methods will be invoked during actual test execution.

3. Demo

Let’s understand the difference between @Mock and @InjectMocks with an example. In this example, we have a class MainClass that has a method save().

MainClass has a dependency on DatabaseDAO and NetworkDAO. When we call MainClass.save() method, it internally calls save methods of both dependent objects.

3.1. System Under Test

public class MainClass {

	DatabaseDAO database;
	NetworkDAO network;

	//Setters and getters

	public boolean save(String fileName)
	{
		database.save(fileName);
		System.out.println("Saved in database in Main class");

		network.save(fileName);
		System.out.println("Saved in network in Main class");

		return true;
	}
}
public class DatabaseDAO {
	public void save(String fileName) {
		System.out.println("Saved in database");
	}
}
public class NetworkDAO {
	public void save(String fileName) {
		System.out.println("Saved in network location");
	}
}

3.2. Unit Test

Let’s write the junit test for MainClass.

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class ApplicationTest
{
	@InjectMocks
	MainClass mainClass;

	@Mock
	DatabaseDAO dependentClassOne;

	@Mock
	NetworkDAO dependentClassTwo;

	@Before
	public void init() {
		MockitoAnnotations.openMocks(this);
	}

	@Test
	public void validateTest()
	{
                //record expectations with mock methods
                when(dependentClassOne.save()).thenReturn(true);
                when(dependentClassTwo.save()).thenReturn(true);

		boolean saved = mainClass.save("temp.txt");
		assertEquals(true, saved);

                //verify recorded expectations
	}
}

4. Conclusion

In this mockito tutorial, we learned the difference between @Mock and @InjectMocks annotations. We learned what happens when we apply these annotations to classes in junit tests.

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

2 thoughts on “Mockito @Mock vs @InjectMocks Annotations”

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.