Mockito et JUnit 5 - Utiliser ExtendWith

Mockito et JUnit 5 - Utiliser ExtendWith

1. introduction

Dans cet article rapide, nous allons montrerhow to integrate Mockito with the JUnit 5 extension model. Pour en savoir plus sur le modèle d'extension JUnit 5, jetez un œil à cearticle.

Tout d'abord, nous allons montrer comment créer une extension qui crée automatiquement des objets simulés pour tout attribut de classe ou paramètre de méthode annoté avec@Mock.

Ensuite, nous utiliserons notre extension Mockito dans une classe de test JUnit 5.

2. Dépendances Maven

2.1. Dépendances requises

Ajoutons les dépendances JUnit 5 (jupiter) etmockito à nospom.xml:


    org.junit.jupiter
    junit-jupiter-engine
    5.3.1
    test


    org.mockito
    mockito-core
    2.21.0
    test

Notez que junit-jupiter-engine est la principale bibliothèque JUnit 5, etjunit-platform-launcher est utilisé avec le plugin Maven et le lanceur IDE.

2.2. Plugin Surefire

Configurons également le plug-in Maven Surefire pour exécuter nos classes de test à l'aide du nouveau programme de lancement de la plate-forme JUnit:


    maven-surefire-plugin
    2.19.1
    
        
             org.junit.platform
             junit-platform-surefire-provider
             1.0.1
         
     

2.3. Dépendances de compatibilité de JUnit 4 IDE

Pour que nos scénarios de test soient compatibles avec JUnit4 (vintage), pour les IDE qui ne prennent pas encore en charge JUnit 5, incluons ces dépendances:


    org.junit.platform
    junit-platform-runner
    1.2.0
    test


     org.junit.vintage
     junit-vintage-engine
     5.2.0
     test

De plus, nous devrions envisager d'annoter toutes nos classes de test avec@RunWith(JUnitPlatform.class)

Les dernières versions dejunit-jupiter-engine,junit-vintage-engine,junit-platform-launcher etmockito-core peuvent être téléchargées depuis Maven Central.

3. Extension Mockito

Mockito fournit une implémentation pour les extensions JUnit5 dans la bibliothèque -mockito-junit-jupiter. Nous allons inclure cette dépendance dans nospom.xml:


    org.mockito
    mockito-junit-jupiter
    2.23.0
    test

4. Construire la classe de test

Construisons notre classe de test et y attachons l’extension Mockito:

@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class UserServiceUnitTest {

    UserService userService;

... //
}

Nous pouvons utiliser l'annotation@Mock pour injecter une simulation pour une variable d'instance que nous pouvons utiliser n'importe où dans la classe de test:

@Mock UserRepository userRepository;

En outre, nous pouvons injecter des objets fantaisie dans les paramètres de la méthode:

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

Veuillez noter l'utilisation deMockito.lenient() ici. Mockito renvoie unUnsupportedStubbingException, lorsqu'un simulacre initialisé n'est pas appelé par l'une des méthodes de test pendant l'exécution. Nous pouvons éviter cette vérification de tronçon stricte en utilisant cette méthode lors de l’initialisation des simulacres.

Nous pouvons même injecter un objet fantaisie dans un paramètre de méthode de test:

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

Notez que la simulationMailClient que nous injectons en tant que paramètre de test ne sera PAS la même instance que celle que nous avons injectée dans la méthodeinit.

5. Conclusion

Junit 5 a fourni un bon modèle pour l’extension. Nous avons démontré une simple extension de Mockito qui simplifiait notre logique de création de maquette.

Tout le code utilisé dans cet article se trouve dans le packagecom.example.junit5.mockito desGitHub project, ainsi que quelques méthodes de test unitaires supplémentaires.