Guide rapide de @RestClientTest dans Spring Boot

Guide rapide sur @RestClientTest dans Spring Boot

1. introduction

Cet article est une introduction rapide à l'annotation@RestClientTest.

La nouvelle annotation simplifie et accélère les tests des clients REST dans vos applications Spring.

2. Prise en charge du client REST dans Spring Boot Pre-1.4

Spring Boot est une infrastructure pratique qui fournit de nombreux beans Spring configurés automatiquement avec des paramètres types vous permettant de vous concentrer moins sur la configuration d'une application Spring et davantage sur votre code et votre logique métier.

Mais dans la version 1.3, nous n'obtenons pas beaucoup d'aide lorsque nous voulons créer ou tester des clients de services REST. Son support pour les clients REST n'est pas très profond.

Pour créer un client pour une API REST - une instanceRestTemplate est généralement utilisée. Habituellement, il doit être configuré avant utilisation et sa configuration peut varier, donc Spring Boot ne fournit aucun beanRestTemplate configuré universellement.

Il en va de même pour tester les clients REST. Avant Spring Boot 1.4.0, la procédure de test d'un client Spring REST n'était pas très différente de celle de toute autre application Spring. Vous devez créer une instanceMockRestServiceServer, la lier à l'instanceRestTemplate testée et lui fournir des réponses simulées aux requêtes, comme ceci:

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer =
  MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting"))
  .andRespond(withSuccess());

// Test code that uses the above RestTemplate ...

mockServer.verify();

Vous devez également initialiser le conteneur Spring et vous assurer que seuls les composants nécessaires sont chargés dans le contexte afin d'accélérer le temps de chargement du contexte (et par conséquent le temps d'exécution du test).

3. Nouvelles fonctionnalités du client REST dans Spring Boot 1.4+

Dans Spring Boot 1.4, l'équipe a déployé des efforts considérables pour simplifier et accélérer la création et les tests des clients REST.

Voyons donc les nouvelles fonctionnalités.

3.1. Ajouter Spring Boot à votre projet

Tout d'abord, vous devez vous assurer que votre projet utilise Spring Boot 1.4.x ou supérieur:


    org.springframework.boot
    spring-boot-starter-parent
     

    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.springframework.boot
        spring-boot-starter-test
        test
    

Les versions les plus récentes peuvent être trouvéeshere.

3.2. RestTemplateBuilder

Spring Boot apporte à la fois lesRestTemplateBuilder auto-configurés pour simplifier la création deRestTemplates et l'annotation correspondante@RestClientTest pour tester les clients créés avecRestTemplateBuilder. Voici comment créer un client REST simple avecRestTemplateBuilder auto-injecté pour vous:

@Service
public class DetailsServiceClient {

    private final RestTemplate restTemplate;

    public DetailsServiceClient(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder.build();
    }

    public Details getUserDetails(String name) {
        return restTemplate.getForObject("/{name}/details",
          Details.class, name);
    }
}

Notez que nous n'avons pas explicitement câblé l'instanceRestTemplateBuilder à un constructeur. Ceci est possible grâce à une nouvelle fonctionnalité Spring appelée injection implicite de constructeur, qui est discutée dansthis article.

RestTemplateBuilder fournit des méthodes pratiques pour enregistrer les convertisseurs de messages, les gestionnaires d'erreurs, les gestionnaires de modèles d'URI, l'autorisation de base et également utiliser tous les personnalisateurs supplémentaires dont vous avez besoin.

3.3. @RestClientTest

Pour tester un tel client REST construit avecRestTemplateBuilder, vous pouvez utiliser une classe de test exécutéeSpringRunner et annotée avec@RestClientTest. Cette annotation désactive la configuration automatique complète et applique uniquement la configuration pertinente aux tests du client REST, c.-à-d. Auto-configuration Jackson ou GSON et beans@JsonComponent, mais pas les beans@Component normaux.

@RestClientTest garantit que la prise en charge de Jackson et de GSON est auto-configurée et ajoute également des instancesRestTemplateBuilder etMockRestServiceServer préconfigurées au contexte. Le bean testé est spécifié avec l'attributvalue oucomponents de l'annotation@RestClientTest:

@RunWith(SpringRunner.class)
@RestClientTest(DetailsServiceClient.class)
public class DetailsServiceClientTest {

    @Autowired
    private DetailsServiceClient client;

    @Autowired
    private MockRestServiceServer server;

    @Autowired
    private ObjectMapper objectMapper;

    @Before
    public void setUp() throws Exception {
        String detailsString =
          objectMapper.writeValueAsString(new Details("John Smith", "john"));

        this.server.expect(requestTo("/john/details"))
          .andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON));
    }

    @Test
    public void whenCallingGetUserDetails_thenClientMakesCorrectCall()
      throws Exception {

        Details details = this.client.getUserDetails("john");

        assertThat(details.getLogin()).isEqualTo("john");
        assertThat(details.getName()).isEqualTo("John Smith");
    }
}

Tout d'abord, nous devons nous assurer que ce test est exécuté avecSpringRunner en ajoutant l'annotation@RunWith(SpringRunner.class).

Alors quoi de neuf?

First - l'annotation@RestClientTest nous permet de spécifier le service exact à tester - dans notre cas, il s'agit de la classeDetailsServiceClient. Ce service sera chargé dans le contexte de test, tandis que tout le reste est filtré.

Cela nous permet de câbler automatiquement l'instanceDetailsServiceClient à l'intérieur de notre test et de laisser tout le reste à l'extérieur, ce qui accélère le chargement du contexte.

Second - comme l'instanceMockRestServiceServer est également configurée pour un test annoté@RestClientTest (et liée à l'instanceDetailsServiceClient pour nous), nous pouvons simplement l'injecter et l'utiliser.

Finally - La prise en charge JSON pour@RestClientTest nous permet d’injecter l’instanceObjectMapper de Jackson pour préparer la valeur de réponse fictiveMockRestServiceServer’s.

Il ne reste plus qu'à exécuter l'appel à notre service et vérifier les résultats.

4. Conclusion

Dans cet article, nous avons présenté la nouvelle annotation@RestClientTest qui permet de tester facilement et rapidement les clients REST créés avec Spring.

Le code source de l'article est disponibleon GitHub.