Mockito und JUnit 5 - ExtendWith verwenden

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.