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 :
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.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)
...
Si une bonne âme passe par ici, je suis tout d'ouïe...
Partager