3 votes

Comment simuler des clients REST lors du test unitaire d'une application Quarkus ?

Quarkus getting started unittest décrit comment simuler des services injectés. Cependant, lorsque j'essaie d'appliquer cela à un client REST injecté, cela ne semble pas fonctionner.

Dans mon application, l'attribut de classe à injecter est défini comme ceci

  @Inject
  @RestClient
  MyService myService;

Dans mon code de test, j'ai créé un service de simulation de cette manière:

@Alternative()
@Priority(1)
@ApplicationScoped
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Veuillez noter que ce service n'est pas enregistré ou annoté en tant que RestClient. Exécuter mes tests unitaires de cette manière donne l'erreur suivante:

org.junit.jupiter.api.extension.TestInstantiationException: TestInstanceFactory [io.quarkus.test.junit.QuarkusTestExtension] n'a pas pu instancier la classe de test [...MyMediatorTest]: io.quarkus.builder.BuildException: Échec de la construction: L'échec de la construction est dû à des erreurs
    [error]: L'étape de construction io.quarkus.arc.deployment.ArcAnnotationProcessor#build a levé une exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Dépendance non satisfaite pour le type ...MyService et les qualificateurs [@RestClient]
    - membre java: ...MyMediator#myService
    - déclaré sur la CLASS bean [types=[java.lang.Object, ...MyMediator], qualifiers=[@Default, @Any], target=...MyMediator]

    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeTestInstanceFactory(ClassTestDescriptor.java:314)
  ...

Je peux probablement résoudre cela en ajoutant une couche de service supplémentaire. Mais cela semble être une mauvaise direction à prendre.

Comment puis-je résoudre cela.

Cordialement,

misl

5voto

geoand Points 10879

Vous n'avez pas besoin d'un autre niveau d'indirection.

Vous pouvez simplement faire :

@Alternative()
@Priority(1)
@ApplicationScoped
@RestClient
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Notez que j'ai ajouté l'annotation @RestClient.

Mise à jour

Il est probablement plus intuitif d'utiliser @RegisterRestClient au lieu de @RestClient comme mentionné dans les commentaires et dans la réponse de @Tushar

Mise à jour 2

Quarkus propose également une prise en charge intégrée des mocks pour les beans CDI, voir https://quarkus.io/guides/getting-started-testing#further-simplification-with-injectmock et https://quarkus.io/blog/mocking/

2voto

isilona Points 21

Je viens de rencontrer le même problème. Il semble y avoir des mises à jour dans la documentation et quelques cas particuliers auxquels j'ai été confronté, mais la recherche google m'a envoyé ici en premier, donc je vais ajouter les résultats de mon enquête pour les lecteurs futurs.

Selon la documentation, vous n'avez plus besoin de créer une classe de simulation https://quarkus.io/guides/getting-started-testing#using-injectmock-with-restclient

mais vous pouvez l'utiliser comme suit

Classe de service

@RegisterRestClient(configKey = "country-api")
@ApplicationScoped
public interface MyService

Utilisation du service

@Inject
@RestClient
MyService myService;

Le simuler dans le test comme suit

@InjectMock
@RestClient 
MyService myService;

Jusque-là tout va bien, mais en suivant la documentation https://quarkus.io/guides/rest-client si vous avez besoin de configKey, vous finirez probablement avec

# Vos propriétés de configuration
country-api/mp-rest/url=https://restcountries.eu/rest #
!!country-api/mp-rest/scope=javax.inject.Singleton # /

dans votre fichier de configuration. Et alors vous rencontrerez ces problèmes

Ability to use InjectMock on MicroProfile RestClient # 8622

Usage of InjectMock on MicroProfile RestClient # 9630

Error when trying to Test RestClient # 12585

qui disent: si vous utilisez configKey avec RegisterRestClient, faites attention À NE PAS AVOIR

country-api/mp-rest/scope=javax.inject.Singleton # 

dans le fichier de configuration qui prendra le dessus avant @ApplicationScoped sur l'interface MyService

1voto

Tushar Points 193

Pour la version 1.1.0.Final de quarkus (la dernière au moment de rédiger ceci), utilisez @RegisterRestClient

@Alternative()
@Priority(1)
@ApplicationScoped
@RegisterRestClient
public class MockMyService extends MyService {
    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

1voto

aiman24 Points 11

Utilisez l'annotation @Mock

import io.quarkus.test.Mock;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import javax.enterprise.context.ApplicationScoped;

@Mock
@ApplicationScoped
@RestClient
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X