Java注解@Mock和@InjectMocks及@Mock和@Spy之间的区别

Java注解@Mock和@InjectMocks及@Mock和@Spy之间的区别

1.@Mock和@InjectMocks的区别
@Mock为您需要的类创建一个模拟实现。
@InjectMocks创建类的一个实例,并将用@Mock或@Spy注释创建的模拟注入到这个实例中。
注意,必须使用@RunWith(MockitoJUnitRunner.class)Mockito.initMocks(this)初始化这些模拟并注入它们。

下面给出一个使用示例:
假设我们有Game和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;
    }
}

如您所见,Game类需要Player类来执行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将使用when和thenReturn方法模拟玩家类及其行为。最后,使用@InjectMocks mockito将把Player放入Game中。

注意,你甚至不必创建new Game对象, mockito会给你注射。

2.我们还将使用@Spy注释获得相同的行为。从中可以看出@Spy和@Mock的区别。

@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();
  }

这是因为Mockito将检查游戏类的Type Signature,即Player和List。

总结:@Spy修饰的外部类,必须是真实存在的,如果没有我们要自己生成创建
@Mock修饰的外部类,是完全模拟出来的,就算项目中没有这个类的实例,也能自己mock出来一个。
@InjectMocks创建类的一个实例,并将用@Mock或@Spy注释创建的模拟注入到这个实例中。