web-dev-qa-db-fra.com

Différence entre MockMvc et RestTemplate dans les tests d'intégration

MockMvc et RestTemplate sont utilisés pour les tests d'intégration avec Spring et JUnit.

La question est: quelle est la différence entre eux et quand devrions-nous choisir l'un plutôt que l'autre?

Voici quelques exemples des deux options:

//MockMVC example
mockMvc.perform(get("/api/users"))
            .andExpect(status().isOk())
            (...)

//RestTemplate example
ResponseEntity<User> entity = restTemplate.exchange("/api/users",
            HttpMethod.GET,
            new HttpEntity<String>(...),
            User.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
43
Denis C de Azevedo

Comme indiqué dans l'article this , vous devez utiliser MockMvc lorsque vous souhaitez tester Côté serveur de l'application:

Spring MVC Test s'appuie sur la demande fictive et la réponse de spring-test et ne nécessite pas de conteneur de servlet en cours d'exécution. La principale différence est que la configuration réelle de Spring MVC est chargée via le framework TestContext et que la demande est effectuée en invoquant en fait DispatcherServlet et la même infrastructure Spring MVC utilisée au moment de l'exécution.

par exemple:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("servlet-context.xml")
public class SampleTests {

  @Autowired
  private WebApplicationContext wac;

  private MockMvc mockMvc;

  @Before
  public void setup() {
    this.mockMvc = webAppContextSetup(this.wac).build();
  }

  @Test
  public void getFoo() throws Exception {
    this.mockMvc.perform(get("/foo").accept("application/json"))
        .andExpect(status().isOk())
        .andExpect(content().mimeType("application/json"))
        .andExpect(jsonPath("$.name").value("Lee"));
  }}

Et RestTemplate vous devez utiliser lorsque vous voulez tester Reste l'application côté client :

Si vous avez du code utilisant le RestTemplate, vous voudrez probablement le tester et pour cela, vous pouvez cibler un serveur en cours d'exécution ou se moquer du RestTemplate. Le côté client REST le support de test offre une troisième alternative, qui consiste à utiliser le RestTemplate réel mais le configurer avec un ClientHttpRequestFactory personnalisé qui vérifie les attentes par rapport au réel demande et renvoie des réponses de talon.

exemple:

RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

mockServer.expect(requestTo("/greeting"))
  .andRespond(withSuccess("Hello world", "text/plain"));

// use RestTemplate ...

mockServer.verify();

lire aussi cet exemple

30
nivash

Avec MockMvc, vous configurez généralement un contexte d'application Web complet et vous moquez des demandes et des réponses HTTP. Ainsi, bien qu'un faux DispatcherServlet soit opérationnel et simule le fonctionnement de votre pile MVC, aucune connexion réseau réelle n'est établie.

Avec RestTemplate, vous devez déployer une instance de serveur réelle pour écouter les requêtes HTTP que vous envoyez.

35

Il est possible d'utiliser à la fois RestTemplate et MockMvc!

Ceci est utile si vous avez un client distinct où vous effectuez déjà le mappage fastidieux des objets Java en URL et conversion vers et depuis Json, et que vous souhaitez réutiliser cela pour vos tests MockMVC.

Voici comment faire:

@RunWith(SpringRunner.class)
@ActiveProfiles("integration")
@WebMvcTest(ControllerUnderTest.class)
public class MyTestShould {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void verify_some_condition() throws Exception {

        MockMvcClientHttpRequestFactory requestFactory = new MockMvcClientHttpRequestFactory(mockMvc);
        RestTemplate restTemplate = new RestTemplate(requestFactory);

        ResponseEntity<SomeClass> result = restTemplate.getForEntity("/my/url", SomeClass.class);

        [...]
    }

}
17
Michael Böckling