J'essaie de simuler un modèle de repos dans ma classe DAO mais Mockito lance une erreur étrange disant qu'il ne peut pas se moquer.
Essayer de couvrir les cas de test unitaires pour mon application Spring Boot version 2.x. J'ai presque essayé toutes les solutions possibles sur Internet, comme la mise à jour de JDK / JRE pour la compilation, mais je suis coincé avec l'erreur suivante:
gradlew test
Voici mon code: p >
build.gradle
gradlew bootRun
MyDao.java
@Bean public RestTemplate restTemplate() { // block of code for SSL config for HTTPS connection return new RestTemplate(); }
MyDaoTest.java
@ExtendWith(MockitoExtension.class) public class MyDaoTest { @Mock private RestTemplate restTemplate; @InjectMocks private MyDao dao; @BeforeEach public void prepare() { ResponseEntity<String> response = new ResponseEntity<>("{name: myname}", HttpStatus.OK); Mockito.doReturn(response).when(restTemplate.getForEntity(Mockito.anyString(), String.class)); } @Test public void testGetSignals() { System.out.println("------------------TEST-------------------"); String result = dao.getSignals(); System.out.println("result ------>" + result); assertEquals("{name: myname}", result); } }
BeanConfig pour RestTemplate
@Repository public class MyDao { @Value("${app.prop.service.url}") private String url; @Autowired public RestTemplate restTemplate; public String getSignals() { System.out.println("url -----------------------> " + url); return new RetryTemplate().execute(context -> { ResponseEntity<String> response = restTemplate.getForEntity(url, String.class); if (response.getStatusCodeValue() == 200) { System.out.println("Server response -> " + response.getBody()); return response.getBody(); } else { throw new RuntimeException("server response status: " + response.getStatusCode()); } }, context -> { System.out.println("retry count: " + context.getRetryCount()); System.err.println("error -> " + context.getLastThrowable()); return null; }); } }
Toutes les suggestions seront vraiment utiles
PS: L'application fonctionne parfaitement grâce à la commande gradle
dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-data-rest' implementation 'org.springframework.retry:spring-retry' implementation 'org.aspectj:aspectjrt' implementation 'org.aspectj:aspectjweaver' implementation 'org.springframework:spring-aop' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0' testCompile 'org.junit.jupiter:junit-jupiter-params:5.2.0' testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.2.0' testImplementation 'org.mockito:mockito-core:2.+' testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3' } test { testLogging.showStandardStreams = true useJUnitPlatform() }
Le problème vient uniquement des tests unitaires
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class org.springframework.web.client.RestTemplate. Mockito can only mock non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list. Java : 1.8 JVM vendor name : Oracle Corporation JVM vendor version : 25.181-b13 JVM name : Java HotSpot(TM) 64-Bit Server VM JVM version : 1.8.0_181-b13 JVM info : mixed mode OS name : Windows 10 OS version : 10.0 Underlying exception : java.lang.IllegalArgumentException: Could not create type at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:115) ....
3 Réponses :
L'une des causes du problème décrit (ou subordonné) pourrait être, puisque RestTemplate
n'est ni "privé" ni "final" et "dit mockable", l'invocation / la dérision de restTemplate.getForEntity ()
... dans le version actuelle , cette méthode est disponible en trois versions / avec des paramètres de surcharge:
... getForEntity (String url, Classe responseType, Object ... uriVariables) ...
... getForEntity (String url, Classe responseType, Map uriVariables) ...
... getForEntity (url URI, classe responseType) ...
Dans votre code (opérationnel), vous semblez utiliser la 1ère saveur, donc sans le changer (le code opérationnel), je propose d'ajuster votre code de test à:
... testImplementation 'org.mockito:mockito-core:2.+' testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3'
Mais le message d'erreur me rend toujours "prudent" et je me demande ... vous êtes à la pointe de la pile junit (5), êtes-vous confiant concernant votre configuration de test !? (libs / config gradle manquant?)
S'il vous plaît, "essayez":
testCompile "org.mockito:mockito-core:2.+" testCompile('org.mockito:mockito-junit-jupiter:2.18.3')
pas:
...restTemplate.getForEntity(Mockito.anyString(), String.class /*!!!*/, ArgumentMatchers.<Object>any());
.. comme indiqué sur dzone's spring-boot-2-with-junit-5-and-mockito-2-for-unit . Si cela (et d'autres conclusions du didacticiel) ne vous aide pas, pensez à vraiment:
le signaler à la liste de diffusion (.)
Et j'ai entendu / lu la première fois (de ma vie):
simuler un modèle de repos dans ma classe DAO
Pensez à nommer votre dao comme "service" (+ les étapes / refactorings correspondants;)
D'accord, j'ai résolu le problème. C'était une incompatibilité de version entre les jars mockito-core et mockito-junit-jupiter, ce qui posait problème.
La dépendance correcte est:
testImplementation 'org.mockito:mockito-core:2.+'
Auparavant, c'était
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0' testCompile 'org.junit.jupiter:junit-jupiter-params:5.2.0' testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.2.0' testImplementation 'org.mockito:mockito-core:2.18.3' testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3'
Gradle choisissait la dernière version de mockito-core jar car il lui était demandé de choisir n'importe quelle version de la série 2.x, comme défini dans le fichier de construction. Je pense que le reste est explicite.
Heureux, tests unitaires! : P
Ce problème m'est arrivé parce que j'exécutais par inadvertance Java 11. Une fois que je suis passé à Java 8, qui est standard pour le projet, le problème a disparu.