What is the difference between @Mock and @InjectMocks in Mockito framework?
13 Answers
@Mock creates a mock. @InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock (or @Spy) annotations into this instance.
Note you must use @RunWith(MockitoJUnitRunner.class) or Mockito.initMocks(this) to initialize these mocks and inject them (JUnit 4).
With JUnit 5, you must use @ExtendWith(MockitoExtension.class).
@RunWith(MockitoJUnitRunner.class) // JUnit 4 // @ExtendWith(MockitoExtension.class) for JUnit 5 public class SomeManagerTest { @InjectMocks private SomeManager someManager; @Mock private SomeDependency someDependency; // this will be injected into someManager // tests... } 10 Comments
Mockito.initMocks(this) is deprecated, Mockito.openMocks(this) should be used.This is a sample code on how @Mock and @InjectMocks works.
Say we have Game and Player class.
class Game { private Player player; public Game(Player player) { this.player = player; } public String attack() { return "Player attack with: " + player.getWeapon(); } } class Player { private String weapon; public Player(String weapon) { this.weapon = weapon; } String getWeapon() { return weapon; } } As you see, Game class need Player to perform an attack.
@RunWith(MockitoJUnitRunner.class) class GameTest { @Mock Player player; @InjectMocks Game game; @Test public void attackWithSwordTest() throws Exception { Mockito.when(player.getWeapon()).thenReturn("Sword"); assertEquals("Player attack with: Sword", game.attack()); } } Mockito will mock a Player class and it's behaviour using when and thenReturn method. Lastly, using @InjectMocks Mockito will put that Player into Game.
Notice that you don't even have to create a new Game object. Mockito will inject it for you.
// you don't have to do this Game game = new Game(player); We will also get same behaviour using @Spy annotation. Even if the attribute name is different.
@RunWith(MockitoJUnitRunner.class) public class GameTest { @Mock Player player; @Spy List<String> enemies = new ArrayList<>(); @InjectMocks Game game; @Test public void attackWithSwordTest() throws Exception { Mockito.when(player.getWeapon()).thenReturn("Sword"); enemies.add("Dragon"); enemies.add("Orc"); assertEquals(2, game.numberOfEnemies()); assertEquals("Player attack with: Sword", game.attack()); } } class Game { private Player player; private List<String> opponents; public Game(Player player, List<String> opponents) { this.player = player; this.opponents = opponents; } public int numberOfEnemies() { return opponents.size(); } // ... That's because Mockito will check the Type Signature of Game class, which is Player and List<String>.
3 Comments
In your test class, the tested class should be annotated with @InjectMocks. This tells Mockito which class to inject mocks into:
@InjectMocks private SomeManager someManager; From then on, we can specify which specific methods or objects inside the class, in this case, SomeManager, will be substituted with mocks:
@Mock private SomeDependency someDependency; In this example, SomeDependency inside the SomeManager class will be mocked.
1 Comment
@Mock annotation mocks the concerned object.
@InjectMocks annotation allows to inject into the underlying object the different (and relevant) mocks created by @Mock.
Both are complementary.
4 Comments
@InjectMocks to construct this class and spy on it too.- @Mock creates a mock implementation for the classes you need.
- @InjectMock creates an instance of the class and injects the mocks that are marked with the annotations @Mock into it.
For example
@Mock StudentDao studentDao; @InjectMocks StudentService service; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); } Here we need the DAO class for the service class. So, we mock it and inject it in the service class instance. Similarly, in Spring framework all the @Autowired beans can be mocked by @Mock in jUnits and injected into your bean through @InjectMocks.
MockitoAnnotations.initMocks(this) method initialises these mocks and injects them for every test method so it needs to be called in the setUp() method.
1 Comment
Though the above answers have covered, I have just tried to add minute detail s which i see missing. The reason behind them(The Why).
Illustration:
Sample.java --------------- public class Sample{ DependencyOne dependencyOne; DependencyTwo dependencyTwo; public SampleResponse methodOfSample(){ dependencyOne.methodOne(); dependencyTwo.methodTwo(); ... return sampleResponse; } } SampleTest.java ----------------------- @RunWith(PowerMockRunner.class) @PrepareForTest({ClassA.class}) public class SampleTest{ @InjectMocks Sample sample; @Mock DependencyOne dependencyOne; @Mock DependencyTwo dependencyTwo; @Before public void init() { MockitoAnnotations.initMocks(this); } public void sampleMethod1_Test(){ //Arrange the dependencies DependencyResponse dependencyOneResponse = Mock(sampleResponse.class); Mockito.doReturn(dependencyOneResponse).when(dependencyOne).methodOne(); DependencyResponse dependencyTwoResponse = Mock(sampleResponse.class); Mockito.doReturn(dependencyOneResponse).when(dependencyTwo).methodTwo(); //call the method to be tested SampleResponse sampleResponse = sample.methodOfSample() //Assert <assert the SampleResponse here> } } Comments
A "mocking framework", which Mockito is based on, is a framework that gives you the ability to create Mock objects ( in old terms these objects could be called shunts, as they work as shunts for dependend functionality ) In other words, a mock object is used to imitate the real object your code is dependend on, you create a proxy object with the mocking framework. By using mock objects in your tests you are essentially going from normal unit testing to integrational testing
Mockito is an open source testing framework for Java released under the MIT License, it is a "mocking framework", that lets you write beautiful tests with clean and simple API. There are many different mocking frameworks in the Java space, however there are essentially two main types of mock object frameworks, ones that are implemented via proxy and ones that are implemented via class remapping.
Dependency injection frameworks like Spring allow you to inject your proxy objects without modifying any code, the mock object expects a certain method to be called and it will return an expected result.
The @InjectMocks annotation tries to instantiate the testing object instance and injects fields annotated with @Mock or @Spy into private fields of the testing object.
MockitoAnnotations.initMocks(this) call, resets testing object and re-initializes mocks, so remember to have this at your @Before / @BeforeMethod annotation.
3 Comments
One advantage you get with the approach mentioned by @Tom is that you don't have to create any constructors in the SomeManager, and hence limiting the clients to instantiate it.
@RunWith(MockitoJUnitRunner.class) public class SomeManagerTest { @InjectMocks private SomeManager someManager; @Mock private SomeDependency someDependency; // this will be injected into someManager //You don't need to instantiate the SomeManager with default contructor at all //SomeManager someManager = new SomeManager(); //Or SomeManager someManager = new SomeManager(someDependency); //tests... } Whether its a good practice or not depends on your application design.
2 Comments
@Mock is used to declare/mock the references of the dependent beans, while @InjectMocks is used to mock the bean for which test is being created.
For example:
public class A{ public class B b; public void doSomething(){ } } test for class A:
public class TestClassA{ @Mocks public class B b; @InjectMocks public class A a; @Test public testDoSomething(){ } } Comments
@InjectMocks annotation can be used to inject mock fields into a test object automatically.
In below example @InjectMocks has used to inject the mock dataMap into the dataLibrary .
@Mock Map<String, String> dataMap ; @InjectMocks DataLibrary dataLibrary = new DataLibrary(); @Test public void whenUseInjectMocksAnnotation_() { Mockito.when(dataMap .get("aData")).thenReturn("aMeaning"); assertEquals("aMeaning", dataLibrary .getMeaning("aData")); } Comments
Many people have given a great explanation here about @Mock vs @InjectMocks. I like it, but I think our tests and application should be written in such a way that we shouldn't need to use @InjectMocks.
Reference for further reading with examples: https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/
1 Comment
Notice that that @InjectMocks are about to be deprecated
deprecate @InjectMocks and schedule for removal in Mockito 3/4
and you can follow @avp answer and link on:
Why You Should Not Use InjectMocks Annotation to Autowire Fields

