What is the difference between @Mock
and @InjectMocks
in Mockito framework?

- 16,038
- 10
- 74
- 104

- 7,321
- 3
- 13
- 5
-
5useful resource https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/ – Dusman Oct 11 '17 at 05:26
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...
}

- 15,324
- 2
- 30
- 40
-
3Does this work for transitive dependencies or only direct members? – Pierre Thibault Jul 08 '19 at 20:30
-
6@PierreThibault Injecting mocks only works for direct members, but you can set a mock to allow deep stubs https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/Mockito.html#RETURNS_DEEP_STUBS – Tom Verelst Jul 09 '19 at 11:18
-
6i feel this is much clear than most of the article online.... that little comments save my ass... – bj4947 Sep 10 '19 at 01:46
-
I have some items that can not provided by @Mock annotation like context. How i can provide that for main class? – Mahdi Feb 18 '20 at 01:57
-
5...and now `Mockito.initMocks(this)` is deprecated, `Mockito.openMocks(this)` should be used. – Artemoon Feb 25 '21 at 05:14
-
I think for `JUnit 5`, if your test is `@SpringBootTest`, the described `@ExtendWith` isn't necessary (@SpringBootTest does its own @ExtendWith [of `SpringExtension.class`]) – cellepo Aug 12 '23 at 00:17
-
@Cellepo Add a citation when you claim https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications – srk Aug 12 '23 at 04:39
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>
.

- 17,295
- 5
- 53
- 64
-
3I sometimes find the testing with the mocking hard to understand and design for a class. However, this example helps a lot to provide the overview. – Arefe May 29 '19 at 12:38
-
Probably too late to this thread but just in case someone sees this: What if the class I am doing an @Mock on itself has some dependencies that need to be injected? For example, say if the weapon was actually a class instead of a String? – Marco Polo Dec 11 '21 at 05:25
-
@MarcoPolo - see [this comment above](https://stackoverflow.com/questions/16467685/difference-between-mock-and-injectmocks#comment100441274_16467893) – striving_coder Aug 05 '22 at 18:35
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.

- 971
- 14
- 30
-
8will this work if someManager has more then one constructor ? what if someManager had 5 constructors how would it know which one you want to use ? – j2emanue Feb 14 '17 at 23:52
@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.

- 21,881
- 15
- 82
- 180
-
1
-
1
-
I have a class that needs to be spied on (via Mockito Spy), and this class has a constructor. So I was thinking of using `@InjectMocks` to construct this class and spy on it too. – IgorGanapolsky Apr 25 '17 at 13:17
-
1Is that what you're looking for? http://stackoverflow.com/a/35969166/985949 – Mik378 Apr 25 '17 at 14:12
- @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.

- 971
- 14
- 30

- 763
- 9
- 19
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,676
- 2
- 30
- 34
-
2I would not say that "By using mock objects in your tests you are essentially going from normal unit testing to integrational testing". For me, mocking is to isolate the fixture to be tested in order to unit-test. Integration testing will use real not mocked dependencies. – WesternGun Jul 13 '18 at 09:29
-
@WesternGun I don't understand how your understanding of mocking is different from the part you quoted – efie Jan 31 '21 at 20:31
-
Mocking is a typical UNIT testing procedure. Integration tests use the real dependencies. This is the plus to unit tests. It run in the real environment, not in an imitated special one to test one case. – SOLID Developper May 12 '21 at 16:04
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>
}
}

- 8,944
- 10
- 43
- 53
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.

- 5,676
- 15
- 68
- 97
-
what if someManager had 3 different constructors, how would it know which one to use ? – j2emanue Feb 14 '17 at 23:51
-
How do you then verify stuff on **someManager** if it is not mocked? – IgorGanapolsky Apr 24 '17 at 20:04
@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(){
}
}

- 971
- 14
- 30

- 321
- 3
- 6
@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"));
}

- 623
- 1
- 10
- 22
@Mock
is for creating and injecting mock instances without having to call Mockito.mock manually. In this example the instance would be ClassB.
Whereas, @InjectMocks
is for injecting mock fields into the tested object automatically. In this case it would be ClassA

- 346
- 3
- 3
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/

- 2,892
- 28
- 34
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

- 56,308
- 23
- 131
- 233