Difference between @Mock and @InjectMocks Difference between @Mock and @InjectMocks java java

Difference between @Mock and @InjectMocks


@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 5public class SomeManagerTest {    @InjectMocks    private SomeManager someManager;    @Mock    private SomeDependency someDependency; // this will be injected into someManager      // tests...}


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 thisGame 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>.


In your test class, the tested class should be annotated with @InjectMocks. This tells Mockito which class to inject mocks into:

@InjectMocksprivate 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:

@Mockprivate SomeDependency someDependency;

In this example, SomeDependency inside the SomeManager class will be mocked.