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注释创建的模拟注入到这个实例中。