Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between @Mock and @InjectMocks

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

like image 734
user2249972 Avatar asked May 09 '13 17:05

user2249972


People also ask

What is the difference between @mock and @MockBean?

We can use the @MockBean to add mock objects to the Spring application context. The mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added.

What is the use of @mock annotation?

@Mock: It is used to mock the objects that helps in minimizing the repetitive mock objects. It makes the test code and verification error easier to read as parameter names (field names) are used to identify the mocks. The @Mock annotation is available in the org. mockito package.

What does @mock annotation mean?

Using the @Mock annotation – allows shorthand creation of objects required for testing. minimizes repetitive mock creation code. makes the test class more readable. makes the verification error easier to read because field name is used to identify the mock.

What is the use of @InjectMocks annotation?

@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed. Injection allows you to, Enable shorthand mock and spy injections.


2 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...  } 
like image 199
Tom Verelst Avatar answered Sep 18 '22 11:09

Tom Verelst


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

like image 20
aldok Avatar answered Sep 19 '22 11:09

aldok