Was ist der Unterschied zwischen @Mock
und @InjectMocks
im Mockito-Framework?
Antworten
Zu viele Anzeigen?@Mock
erstellt ein Mock-Objekt. @InjectMocks
erstellt eine Instanz der Klasse und injiziert die Mock-Objekte, die mit den @Mock
(oder @Spy
) Annotationen erstellt wurden, in diese Instanz.
Bitte beachten Sie, dass Sie @RunWith(MockitoJUnitRunner.class)
oder Mockito.initMocks(this)
verwenden müssen, um diese Mock-Objekte zu initialisieren und sie zu injizieren (JUnit 4).
Bei JUnit 5 müssen Sie @ExtendWith(MockitoExtension.class)
verwenden.
@RunWith(MockitoJUnitRunner.class) // JUnit 4
// @ExtendWith(MockitoExtension.class) für JUnit 5
public class SomeManagerTest {
@InjectMocks
private SomeManager someManager;
@Mock
private SomeDependency someDependency; // dieses wird in someManager injiziert
// tests...
}
Dies ist ein Beispielcode dafür, wie @Mock
und @InjectMocks
funktionieren.
Angenommen, wir haben die Klassen Game
und Player
.
class Game {
private Player player;
public Game(Player player) {
this.player = player;
}
public String attack() {
return "Spieler greift an mit: " + player.getWeapon();
}
}
class Player {
private String weapon;
public Player(String weapon) {
this.weapon = weapon;
}
String getWeapon() {
return weapon;
}
}
Wie Sie sehen, benötigt die Klasse Game
die Klasse Player
, um einen Angriff
durchzuführen.
@RunWith(MockitoJUnitRunner.class)
class GameTest {
@Mock
Player player;
@InjectMocks
Game game;
@Test
public void attackWithSwordTest() throws Exception {
Mockito.when(player.getWeapon()).thenReturn("Schwert");
assertEquals("Spieler greift an mit: Schwert", game.attack());
}
}
Mockito wird eine Player-Klasse und ihr Verhalten mit den Methoden when
und thenReturn
mocken. Schließlich wird Mockito mit @InjectMocks
diesen Player
in das Game
einfügen.
Beachten Sie, dass Sie nicht einmal ein neues Game-Objekt erstellen müssen. Mockito fügt es für Sie ein.
// das müssen Sie nicht machen
Game game = new Game(player);
Durch die Verwendung der Annotation @Spy
erhalten wir dasselbe Verhalten. Auch wenn der Attributname unterschiedlich ist.
@RunWith(MockitoJUnitRunner.class)
public class GameTest {
@Mock Player player;
@Spy List enemies = new ArrayList<>();
@InjectMocks Game game;
@Test public void attackWithSwordTest() throws Exception {
Mockito.when(player.getWeapon()).thenReturn("Schwert");
enemies.add("Drache");
enemies.add("Ork");
assertEquals(2, game.numberOfEnemies());
assertEquals("Spieler greift an mit: Schwert", game.attack());
}
}
class Game {
private Player player;
private List opponents;
public Game(Player player, List opponents) {
this.player = player;
this.opponents = opponents;
}
public int numberOfEnemies() {
return opponents.size();
}
// ...
Dies liegt daran, dass Mockito die Type-Signatur
der Game-Klasse überprüfen wird, die Player
und List
ist.
In Ihrer Testklasse sollte die getestete Klasse mit @InjectMocks
annotiert sein. Dies teilt Mockito mit, in welche Klasse Mocks eingefügt werden sollen:
@InjectMocks
private SomeManager someManager;
Von da an können wir angeben, welche spezifischen Methoden oder Objekte innerhalb der Klasse, in diesem Fall SomeManager
, durch Mocks ersetzt werden:
@Mock
private SomeDependency someDependency;
In diesem Beispiel wird SomeDependency
innerhalb der Klasse SomeManager
gemockt.
- @Mock erstellt eine Mock-Implementierung für die Klassen, die Sie benötigen.
- @InjectMock erstellt eine Instanz der Klasse und fügt die Mocks ein, die mit den Annotationen @Mock markiert sind.
Zum Beispiel
@Mock
StudentDao studentDao;
@InjectMocks
StudentService service;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
Hier benötigen wir die DAO-Klasse für die Service-Klasse. Wir mocken sie und fügen sie in die Instanz der Service-Klasse ein. Ähnlich können in Spring Framework alle mit @Autowired annotierten Beans in jUnits gemockt und in Ihren Bean durch @InjectMocks eingesetzt werden.
Die Methode MockitoAnnotations.initMocks(this)
initialisiert diese Mocks und fügt sie für jede Testmethode ein, daher muss sie in der setUp()
-Methode aufgerufen werden.
Dieser Link enthält ein gutes Tutorial für das Mockito Framework
- See previous answers
- Weitere Antworten anzeigen