Mockito und JUnit 5 - Verwenden von ExtendWith
1. Einführung
In diesem kurzen Artikel zeigen wirhow to integrate Mockito with the JUnit 5 extension model. Weitere Informationen zum JUnit 5-Erweiterungsmodell finden Sie inarticle.
Zunächst zeigen wir, wie Sie eine Erweiterung erstellen, die automatisch Scheinobjekte für alle Klassenattribute oder Methodenparameter erstellt, die mit@Mock versehen sind.
Dann verwenden wir unsere Mockito-Erweiterung in einer JUnit 5-Testklasse.
2. Maven-Abhängigkeiten
2.1. Erforderliche Abhängigkeiten
Fügen wir die Abhängigkeiten von JUnit 5 (Jupiter) undmockitozu unserenpom.xmlhinzu:
org.junit.jupiter
junit-jupiter-engine
5.3.1
test
org.mockito
mockito-core
2.21.0
test
Beachten Sie, dass junit-jupiter-engine die Hauptbibliothek von JUnit 5 ist undjunit-platform-launcher mit dem Maven-Plugin und dem IDE-Launcher verwendet wird.
2.2. Surefire Plugin
Lassen Sie uns das Maven Surefire-Plugin auch so konfigurieren, dass unsere Testklassen mit dem neuen JUnit-Plattform-Launcher ausgeführt werden:
maven-surefire-plugin
2.19.1
org.junit.platform
junit-platform-surefire-provider
1.0.1
2.3. JUnit 4 IDE-Kompatibilitätsabhängigkeiten
Damit unsere Testfälle mit JUnit4 (Vintage) kompatibel sind, schließen wir für IDEs, die JUnit 5 noch nicht unterstützen, die folgenden Abhängigkeiten ein:
org.junit.platform
junit-platform-runner
1.2.0
test
org.junit.vintage
junit-vintage-engine
5.2.0
test
Außerdem sollten wir erwägen, alle unsere Testklassen mit@RunWith(JUnitPlatform.class) zu versehen
Die neuesten Versionen vonjunit-jupiter-engine,junit-vintage-engine,junit-platform-launcher undmockito-core können von Maven Central heruntergeladen werden.
3. Mockito-Erweiterung
Mockito bietet eine Implementierung für JUnit5-Erweiterungen in der Bibliothek -mockito-junit-jupiter. Wir werden diese Abhängigkeit in unserepom.xml: aufnehmen
org.mockito
mockito-junit-jupiter
2.23.0
test
4. Erstellen der Testklasse
Bauen wir unsere Testklasse auf und hängen Sie die Mockito-Erweiterung daran an:
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class UserServiceUnitTest {
UserService userService;
... //
}
Wir können die Annotation@Mockverwenden, um ein Modell für eine Instanzvariable einzufügen, die wir an einer beliebigen Stelle in der Testklasse verwenden können:
@Mock UserRepository userRepository;
Wir können auch Mock-Objekte in Methodenparameter einfügen:
@BeforeEach
void init(@Mock SettingRepository settingRepository) {
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
Mockito.lenient().when(settingRepository.getUserMinAge()).thenReturn(10);
when(settingRepository.getUserNameMinLength()).thenReturn(4);
Mockito.lenient().when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
}
Bitte beachten Sie die Verwendung vonMockito.lenient() hier. Mockito löst einUnsupportedStubbingException, aus, wenn ein initialisierter Mock während der Ausführung nicht von einer der Testmethoden aufgerufen wird. Wir können diese strenge Stub-Überprüfung vermeiden, indem wir diese Methode beim Initialisieren der Mocks verwenden.
Wir können sogar ein Scheinobjekt in einen Testmethodenparameter einfügen:
@Test
void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) {
// Given
user = new User("Jerry", 12);
when(userRepository.insert(any(User.class))).then(new Answer() {
int sequence = 1;
@Override
public User answer(InvocationOnMock invocation) throws Throwable {
User user = (User) invocation.getArgument(0);
user.setId(sequence++);
return user;
}
});
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
// When
User insertedUser = userService.register(user);
// Then
verify(userRepository).insert(user);
Assertions.assertNotNull(user.getId());
verify(mailClient).sendUserRegistrationMail(insertedUser);
}
Beachten Sie, dass dasMailClient-Modell, das wir als Testparameter injizieren, NICHT dieselbe Instanz ist, die wir in dieinit-Methode injiziert haben.
5. Fazit
Junit 5 hat ein schönes Modell zur Erweiterung bereitgestellt. Wir haben eine einfache Mockito-Erweiterung gezeigt, die unsere Logik zur Erstellung von Mocks vereinfacht hat.
Der gesamte in diesem Artikel verwendete Code befindet sich im Paketcom.example.junit5.mockito derGitHub project, zusammen mit einigen zusätzlichen Unit-Test-Methoden.