web-dev-qa-db-ja.com

統合テストでのMockMvcとRestTemplateの違い

MockMvcRestTemplate の両方が、SpringおよびJUnitとの統合テストに使用されます。

質問は次のとおりです。それらの違いは何ですか?また、どちらを選択するかはいつですか?

以下に両方のオプションの例を示します。

//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

this の記事で述べたように、テストする場合はMockMvcを使用する必要がありますサーバー側アプリケーション:

Spring MVCテストは、spring-test実行中のサーブレットコンテナは必要ありません。主な違いは、実際のSpring MVC構成はTestContextフレームワークを介して読み込まれ、DispatcherServletおよび実行時に使用されるすべての同じSpring MVCインフラストラクチャを実際に呼び出すことによって要求が実行されることです。

例えば:

@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"));
  }}

そして、RestTemplateをテストするときに使用する必要がありますRest Client-side application:

RestTemplateを使用するコードがある場合は、おそらくテストして、実行中のサーバーをターゲットにするか、RestTemplateをモックすることができます。クライアント側のREST=テストサポートは、実際のRestTemplateを使用しますが、実際の期待値をチェックするカスタムClientHttpRequestFactoryを使用して構成する3番目の選択肢を提供しますスタブ応答を要求して返します。

例:

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

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

// use RestTemplate ...

mockServer.verify();

この例 も読む

30
nivash

MockMvcを使用すると、通常、Webアプリケーションコンテキスト全体を設定し、HTTPリクエストとレスポンスをモックします。そのため、MVCスタックの機能をシミュレートする偽のDispatcherServletが実行されていますが、実際のネットワーク接続は行われていません。

RestTemplateでは、送信するHTTPリクエストをリッスンするために実際のサーバーインスタンスをデプロイする必要があります。

35

RestTemplateとMockMvcの両方を使用することができます!

これは、別のクライアントで既にJavaオブジェクトからURLへの退屈なマッピングを行い、Jsonとの間で変換を行っている場合、MockMVCテストで再利用したい場合に便利です。

方法は次のとおりです。

@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