春の統合テスト

1概要

統合テストは、システムのエンドツーエンドの動作を検証することによって、アプリケーション開発サイクルにおいて重要な役割を果たします。

この記事では、サーブレット・コンテナーを明示的に開始せずにコントローラーをテストする統合テストを作成して実行するために、Spring MVCテストフレームワークをどのように活用できるかを説明します。

2準備

この記事で説明しているように、統合テストを実行するには、以下のMaven依存関係が必要です。何よりもまず最新のhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22junit%22%20AND%20a%3A%22junit%22[JUnit]およびhttps://search .maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework%22%20AND%20a%3A%22spring-test%22[春のテスト]依存関係:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.2.RELEASE</version>
    <scope>test</scope>
</dependency>

結果を効果的にアサートするために、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.hamcrest%22%20AND%20a%3A%22hamcrest-も使用します。ライブラリ%22[Hamcrest]およびhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22com.jayway.jsonpath%22%20AND%20a%3A%22json-path%22[JSONパス]:

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
    <scope>test</scope>
</dependency>

3 Spring MVCテスト設定

それでは、Spring対応のテストを構成して実行する方法を紹介しましょう。

** 3.1. テストでSpringを有効にする+

**

まず、Spring対応のテストはすべて @ RunWith(SpringJUnit4ClassRunner.class) の助けを借りて実行されます。ランナーは、基本的にSpring Testフレームワークを使い始めるための入り口です。

また、コンテキスト設定をロードし、テストが使用するコンテキストをブートストラップするための @ ContextConfiguration アノテーションも必要です。

みてみましょう:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationConfig.class })
@WebAppConfiguration
public class GreetControllerIntegrationTest {
    ....
}

@ ContextConfigurationで、この特定のテストに必要な設定を読み込む ApplicationConfig.class__ configクラスをどのように提供したかに注目してください。

ここでは、コンテキスト設定を指定するためにJava設定クラスを使用しました。同様に、XMLベースの設定を使うことができます。

@ContextConfiguration(locations={""})

最後に、テストには** @ WebAppConfiguration という注釈が付けられ、Webアプリケーションのコンテキストがロードされます。

デフォルトでは、デフォルトのパス src/main/webapp でルートWebアプリケーションを探します。次のようにvalue引数を渡すことで位置を上書きすることができます。

@WebAppConfiguration(value = "")

3.2. WebApplicationContext オブジェクト

WebApplicationContext wac )はWebアプリケーション設定を提供します。すべてのアプリケーションBeanとコントローラをコンテキストにロードします。

これでWebアプリケーションのコンテキストをテストに結び付けることができます。

@Autowired
private WebApplicationContext wac;

3.3. WebコンテキストBeanのモック

MockMvc は、Spring MVCのテストをサポートします。すべてのWebアプリケーションBeanをカプセル化し、それらをテストに使用できるようにします。

使い方を見てみましょう。

private MockMvc mockMvc;
@Before
public void setup() throws Exception {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}

@ Before アノテーション付きメソッドで mockMvc オブジェクトを初期化する必要があるので、テストのたびに初期化する必要はありません。

3.4. テスト設定の確認

ここでのチュートリアルでは、 WebApplicationContext オブジェクト( wac )が正しく読み込まれていることを実際に確認しましょう。また、正しい servletContext が添付されていることを確認します。

@Test
public void givenWac__whenServletContext__thenItProvidesGreetController() {
    ServletContext servletContext = wac.getServletContext();

    Assert.assertNotNull(servletContext);
    Assert.assertTrue(servletContext instanceof MockServletContext);
    Assert.assertNotNull(wac.getBean("greetController"));
}

GreetController.java BeanがWebコンテキストに存在することも確認しています。これにより、Spring Beanが正しくロードされます。

これで統合テストの設定は完了です。 MockMvc オブジェクトを使用してリソースメソッドをテストする方法を見てみましょう。

4統合テストの書き方

このセクションでは、テストフレームワークを通して利用可能な基本操作について説明します。

パス変数とパラメータを使用してリクエストを送信する方法を示します。

また、適切なビュー名が解決されたこと、またはレスポンスボディが予想どおりであることをどのように主張するかを示す、いくつかの例を示します。

以下のスニペットは、M __ockMvcRequestBuilders または MockMvcResultMatchers__クラスからの静的インポートを使用します。

4.1. ビュー名を確認

テストから /homePage エンドポイントを____:として呼び出しましょう。

http://localhost:8080/spring-mvc-test/----

または

[source,html,gutter:,true]
** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenHomePageURI whenMockMVC thenReturnsIndexJSPViewName() { this.mockMvc.perform(get("/homePage")).andDo(print())

      .andExpect(view().name("index"));
}
それを分解しましょう。

**  __ **  perform()**  __メソッドはgetリクエストメソッドを呼び出します。

**  __ResultActions__ ** 。この結果を使用して、アサーションの予想を立てることができます。
コンテンツ、HTTPステータス、ヘッダなどの応答時
**  __ **  andDo(print())**  __はリクエストとレスポンスをプリントします。これは

エラーが発生した場合に詳細ビューを取得するのに役立ちます
**  __ **  andExpect()**  __は与えられた引数を期待します。私たちの場合は

「index」が**  __MockMvcResultMatchers.view()__ ** で返されることを期待しています

====  **  4.2. レスポンスボディを確認**

テストから__/greet__エンドポイントを呼び出します。

[source,html,gutter:,true]
** 期待される出力:**

[source,javascript,gutter:,true]

{ "id": 1, "message": "Hello World!!!" }

** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenGreetURI whenMockMVC thenVerifyResponse() { MvcResult mvcResult = this.mockMvc.perform(get("/greet")) .andDo(print()).andExpect(status().isOk()) .andExpect(jsonPath("$.message").value("Hello World!!!")) .andReturn();

    Assert.assertEquals("application/json;charset=UTF-8",
      mvcResult.getResponse().getContentType());
}
何が起こっているのかを正確に見てみましょう。

**  **  __andExpect(MockMvcResultMatchers.status()。isOk())__ ** は、それを検証します。

応答httpステータスは__Ok__、つまり__200__です。これにより、リクエストが確実に
正常に実行された
**  __ **  andExpect(MockMvcResultMatchers.jsonPath(“ $。message”))。value(“こんにちは

世界!!!”))**  __応答内容がと一致することを確認します
引数“ __Hello World !!! __”。ここでは抽出する__jsonPath__を使いました
応答内容と要求された値の提供
**  __ **  andReturn()**  __は、使用される__MvcResult__オブジェクトを返します。

図書館では達成できないことを検証しなければなりません。 __MvcResult__オブジェクトから抽出されたレスポンスのコンテンツタイプに一致するように__assertEquals__を追加したことがわかります。

====  **  4.3. パス変数を使用して__GET__リクエストを送信する**

テストから__/greetWithPathVariable/\ {name} __エンドポイントを呼び出します。

[source,html,gutter:,true]
** 期待される出力:**

[source,javascript,gutter:,true]

{ "id": 1, "message": "Hello World John!!!" }

** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenGreetURIWithPathVariable whenMockMVC thenResponseOK() { this.mockMvc .perform(get("/greetWithPathVariable/{name}", "John")) .andDo(print()).andExpect(status().isOk())

      .andExpect(content().contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World John!!!"));
}
__ **  MockMvcRequestBuilders.get(“/greetWithPathVariable/\ {name}”、“ John”)**  __要求を“ __/greetWithPathVariable/John__”として送信します。

読みやすさとURLに動的に設定されるパラメータが何かを知ることに関してこれはより簡単になります。このメソッドはパスパラメータの数を渡すことを制限しません。

====  **  4.4. クエリパラメータを指定して__GET__リクエストを送信する**

テストから__/greetWithQueryVariable?name = \ {name} __エンドポイントを呼び出します。

[source,html,gutter:,true]

http://localhost:8080/spring-mvc-test /greetWithQueryVariable?name=John%20Doe

** 期待される出力:**

[source,javascript,gutter:,true]

{ "id": 1, "message": "Hello World John Doe!!!" }

** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenGreetURIWithQueryParameter whenMockMVC thenResponseOK() { this.mockMvc.perform(get("/greetWithQueryVariable") .param("name", "John Doe")).andDo(print()).andExpect(status().isOk()) .andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.message").value("Hello World John Doe!!!")); }

__/greetWithQueryVariable?name = John%20Doe“ .__

クエリパラメータは、URIテンプレートスタイルを使用して実装することもできます。

[source,java,gutter:,true]

this.mockMvc.perform( get("/greetWithQueryVariable?name={name}", "John Doe"));

====  **  4.5.  __POST__リクエストを送信**

テストから__/greetWithPost__エンドポイントを呼び出します。

[source,html,gutter:,true]
** 期待される出力:**

[source,javascript,gutter:,true]

{ "id": 1, "message": "Hello World!!!" }

** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenGreetURIWithPost whenMockMVC thenVerifyResponse() { this.mockMvc.perform(post("/greetWithPost")).andDo(print()) .andExpect(status().isOk()).andExpect(content() .contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.message").value("Hello World!!!")); }

__ **  MockMvcRequestBuilders.post(“/greetWithPost”)**  __は投稿要求を送信します。パス変数とクエリパラメータは、以前と同じように設定できますが、フォームデータはクエリパラメータと同様に__param()__メソッドでのみ設定できます。

[source,html,gutter:,true]
** フォームデータ:**

[source,text,gutter:,true]

id=1;name=John%20Doe

** 期待される出力:**

[source,javascript,gutter:,true]

{ "id": 1, "message": "Hello World John Doe!!!" }

** コードスニペット:**

[source,java,gutter:,true]

@Test public void givenGreetURIWithPostAndFormData whenMockMVC thenResponseOK() { this.mockMvc.perform(post("/greetWithPostAndFormData").param("id", "1") .param("name", "John Doe")).andDo(print()).andExpect(status().isOk())

      .andExpect(content().contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World John Doe!!!"))
      .andExpect(jsonPath("$.id").value(1));
}
上記のコードスニペットでは、2つのパラメータidを「1」として、名前を「John Doe」として追加しました。

[[Conclusion]]

===  **  5結論**

このクイックチュートリアルでは、Spring対応の簡単な統合テストをいくつか実装しました。

また、アプリケーションのエンドポイントを呼び出す際に重要な役割を果たした__WebApplicationContext__および__MockMVC__オブジェクトの作成についても説明しました。

さらに詳しく見ていくと、__GET__および__POST__要求をさまざまなパラメーター受け渡しとともに送信する方法と、HTTP応答状況、ヘッダー、および内容の確認方法について説明しました。

最後に、これらすべての例とコードスニペットの実装は次のとおりです。
で利用可能
https://github.com/eugenp/tutorials/tree/master/spring-mvc-java[GitHub]** ** .** **