IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tests et Performance Java Discussion :

Simuler le résultat d'une méthode interne à la classe que l'on teste


Sujet :

Tests et Performance Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Reconversion professionnelle
    Inscrit en
    novembre 2021
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Reconversion professionnelle

    Informations forums :
    Inscription : novembre 2021
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Simuler le résultat d'une méthode interne à la classe que l'on teste
    Bonjour à tous,

    Je suis en train de me former sur Java et je suis actuellement en train de rédiger des tests sur le backend de mon Api rest (Junit5/Mockito).

    Jusqu'à présent, j'avais réussi à faire mes tests sur des méthodes simples (juste avec les assertions Junit) et sur des méthodes qui appelait d'autres méthodes d'autres classes avec les mocks. Mon problème aujourd'hui est que je dois tester une méthode qui fait un appel externe a la classe (pas de souci avec mock) mais aussi à une méthode public dans la même classe. Et malgré plusieurs essais différents Notamment avec @Spy, je n'y arrive pas, soit j'ai des erreurs, soit ma simulation ne fonctionne pas et fait un vrai appel.

    Voici la classe que j'essaye de tester :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    @Service
    public class PersonService {
     
        private final PersonRepository personRepository;
        private final AddressService addressService;
     
        public PersonService(PersonRepository personRepository, AddressService addressService) {
            this.personRepository = personRepository;
            this.addressService = addressService;
        }
     
        public void deletePerson(String firstName, String lastName) {
            Person person = find(firstName, lastName);
            personRepository.delete(person);
        }
     
           public Person find(String firstName, String lastName)  {
            Optional<Person> existingPerson = Optional.ofNullable(personRepository.findOneByFirstNameAndLastName(firstName, lastName));
            if(existingPerson.isEmpty()) {
                throw new PersonNotFoundException(firstName, lastName);
            }
            return personRepository.findOneByFirstNameAndLastName(firstName,lastName);
        }

    la méthode qui me pose problème est la méthode deletePerson(), car elle fait appel à find() qui est dans la même classe.
    Voici ma classe de test :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    @SpringBootTest
    class PersonServiceTest {
     
        PersonRepository personRepository = mock(PersonRepository.class);
        AddressService addressService = mock(AddressService.class);
     
        PersonService classUnderTest = new PersonService(personRepository, addressService);
     
        PersonService personServiceSpy = Mockito.spy(classUnderTest);
     
     
        Address address = new Address("5, rue des peupliers");
        Person person = new Person("Roger","Borgne",address,
                "Saint-Lambert","45890","04 85 74 32 45",
                "activeService@gmail.com");
     
     
        @Test
        void deletePerson() {
            Mockito.doReturn(person).when(personServiceSpy.find(person.getFirstName(),person.getLastName()));    // Ligne du dernière essai
            doNothing().when(personRepository).delete(person);
     
            verify(personServiceSpy,times(1)).find(person.getFirstName(),person.getLastName());
        }
     
        @Test
        void find() {
            when(personRepository.findOneByFirstNameAndLastName("Roger", "Borgne")).thenReturn(person);
            classUnderTest.find(person.getFirstName(), person.getLastName());
            verify(personRepository, times(2)).findOneByFirstNameAndLastName("Roger","Borgne");
        }
     
     
    // Autre essai que j'ai pu tenter sans résultat probant.
            // when(personServiceSpy.find(person.getFirstName(),person.getLastName())).thenReturn(person);             
            //Mockito.doReturn(person).when(personServiceSpy).find(person.getFirstName(),person.getLastName());

    Mon test sur find() passe bien au vert, ce qui me fait dire que mon mock de personRepository, n'est pas problématique. Pour la simulation de find() dans deletePerson(),j'ai essayé plusieurs configurations selon les ressources que j'ai pu trouver, ici ou sur internet anglophone (majoritairement baeldung, codeforweek et stackOverFlow), aucune ne marche. La dernière (celle en condition dans ma classe de test actuellement) me renvoi une :


    org.mockito.exceptions.misusing.UnfinishedStubbingException:
    Unfinished stubbing detected here:
    -> at fr.vertours.safetynet.service.PersonServiceTest.deletePerson(PersonServiceTest.java:93)

    E.g. thenReturn() may be missing.
    Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
    Hints:
    1. missing thenReturn()
    2. you are trying to stub a final method, which is not supported
    3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed


    at fr.vertours.safetynet.service.PersonServiceTest.deletePerson(PersonServiceTest.java:93)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    ...
    Bien que le message d'erreur propose des indices de solution, rien n'y fait, j'ai beau tourner les choses dans tous les sens, il me manque une compréhension.

    Si une bonne âme passe par ici, je suis tout d'ouïe...

  2. #2
    Membre actif
    Homme Profil pro
    Architecte technique
    Inscrit en
    mai 2020
    Messages
    189
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : mai 2020
    Messages : 189
    Points : 249
    Points
    249
    Par défaut
    Bonjour,

    Pourquoi ne pas mocker le comportement du repository pour find et delete dans votre test sur delete ?
    Vious ne pouvez pas mocker "find" dans le service, mais vous savez comment votre delete va se comporter.

    Votre test ne valide pas seuelement que le delete est fait sur le repository mais aussi que votre service s'assure de l'existence d'une personne avant de la supprimer.

Discussions similaires

  1. utiliser le résultat d'une méthode
    Par ebenmous dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 20/06/2011, 15h53
  2. Réponses: 3
    Dernier message: 22/03/2011, 08h41
  3. OO comment utiliser une méthode interne
    Par Jasmine80 dans le forum Bioinformatique
    Réponses: 2
    Dernier message: 02/09/2009, 09h28
  4. Résultat d'une méthode. Affectation ou modification ?
    Par kernelfailure dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/06/2009, 23h19
  5. récupérer résultat d'une méthode
    Par kakuzu dans le forum Général Python
    Réponses: 3
    Dernier message: 07/04/2008, 15h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo