Springでの統合テスト
1. 概要
統合テストは、システムのエンドツーエンドの動作を検証することにより、アプリケーション開発サイクルで重要な役割を果たします。
この記事では、Spring MVCテストフレームワークを活用して、サーブレットコンテナを明示的に起動せずにコントローラーをテストする統合テストを作成および実行する方法を説明します。
2. 準備
この記事で説明されているように、統合テストを実行するには、次のMaven依存関係が必要です。 何よりもまず、最新のJUnitとSpring testの依存関係:
junit
junit
4.12
test
org.springframework
spring-test
4.3.2.RELEASE
test
org.hamcrest
hamcrest-library
1.3
test
com.jayway.jsonpath
json-path
2.2.0
test
3. SpringMVCテスト構成
次に、Spring対応のテストを構成して実行する方法を紹介します。
3.1. テストでSpringを有効にする
まず、Spring対応のテストは@RunWith(SpringJUnit4ClassRunner.class)を使用して実行されます。ランナーは基本的に、SpringTestフレームワークの使用を開始するためのエントリポイントです。
また、コンテキスト構成とbootstrap the context that the test will useをロードするための@ContextConfigurationアノテーションも必要です。
みてみましょう:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationConfig.class })
@WebAppConfiguration
public class GreetControllerIntegrationTest {
....
}
@ContextConfiguration,で、この特定のテストに必要な構成をロードするApplicationConfig.class構成クラスを提供したことに注目してください。
ここでは、コンテキスト設定を指定するためにJava設定クラスを使用しました。同様に、XMLベースの構成を使用できます。
@ContextConfiguration(locations={""})
最後に–テストにも@WebAppConfiguration – which will load the web application context.の注釈が付けられます
デフォルトでは、デフォルトのパスsrc/main/webappでルートWebアプリケーションを検索します。値の引数を次のように渡すことで、場所を上書きできます。
@WebAppConfiguration(value = "")
3.2. WebApplicationContextオブジェクト
WebApplicationContext(wac)は、Webアプリケーション構成を提供します。 すべてのアプリケーションBeanとコントローラーをコンテキストにロードします。
これで、Webアプリケーションコンテキストをテストに直接接続できるようになります。
@Autowired
private WebApplicationContext wac;
3.3. WebコンテキストBeanのモック
MockMvcは、SpringMVCテストのサポートを提供します。 すべての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コンテキストに存在することも確認していることに注意してください。これにより、SpringBeanが適切にロードされます。
この時点で、統合テストのセットアップが完了しました。 MockMvcオブジェクトを使用してリソースメソッドをテストする方法を見てみましょう。
4. 統合テストの作成
このセクションでは、テストフレームワークで利用できる基本的な操作について説明します。
パス変数とパラメータを使用してリクエストを送信する方法を示します。 また、適切なビュー名が解決されたこと、または応答本文が期待どおりであることを表明する方法を示すいくつかの例を示します。
次のスニペットは、MockMvcRequestBuildersまたはMockMvcResultMatchersクラスからの静的インポートを使用しています。
4.1. ビュー名を確認する
テストから/homePageエンドポイントを:として呼び出しましょう
http://localhost:8080/spring-mvc-test/
or
http://localhost:8080/spring-mvc-test/homePage
コードスニペット:
@Test
public void givenHomePageURI_whenMockMVC_thenReturnsIndexJSPViewName() {
this.mockMvc.perform(get("/homePage")).andDo(print())
.andExpect(view().name("index"));
}
それを分解しましょう:
-
perform()メソッドは、ResultActionsを返すgetrequestメソッドを呼び出します。 この結果を使用して、コンテンツ、HTTPステータス、ヘッダーなどの応答にアサーションを期待できます。
-
andDo(print())は要求と応答を出力します。 これは、エラーの場合に詳細ビューを取得するのに役立ちます
-
andExpect()は、指定された引数を期待します。 この場合、「インデックス」がMockMvcResultMatchers.view()を介して返されることを期待しています。
4.2. 応答本文を確認する
テストから/greetエンドポイントを次のように呼び出します。
http://localhost:8080/spring-mvc-test/greet
期待される出力:
{
"id": 1,
"message": "Hello World!!!"
}
コードスニペット:
@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!!!”))は、応答の内容が引数「Hello World!!!」と一致することを確認します。 ここでは、応答コンテンツを抽出して要求された値を提供するjsonPathを使用しました
-
andReturn()は、ライブラリで達成できないものを検証する必要がある場合に、使用されるMvcResultオブジェクトを返します。 MvcResultオブジェクトから抽出された応答のコンテンツタイプに一致するようにassertEqualsを追加したことがわかります。
4.3. パス変数を使用してGETリクエストを送信する
テストから/greetWithPathVariable/{name}エンドポイントを次のように呼び出します。
http://localhost:8080/spring-mvc-test/greetWithPathVariable/John
期待される出力:
{
"id": 1,
"message": "Hello World John!!!"
}
コードスニペット:
@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}エンドポイントを次のように呼び出します。
http://localhost:8080/spring-mvc-test
/greetWithQueryVariable?name=John%20Doe
期待される出力:
{
"id": 1,
"message": "Hello World John Doe!!!"
}
コードスニペット:
@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!!!"));
}
param(“name”, “John Doe”)は、GETリクエストにクエリパラメータを追加します。 「/greetWithQueryVariable?name=John%20Doe“.」に似ています
クエリパラメータは、URIテンプレートスタイルを使用して実装することもできます。
this.mockMvc.perform(
get("/greetWithQueryVariable?name={name}", "John Doe"));
4.5. POSTリクエストを送信する
テストから/greetWithPostエンドポイントを次のように呼び出します。
http://localhost:8080/spring-mvc-test/greetWithPost
期待される出力:
{
"id": 1,
"message": "Hello World!!!"
}
コードスニペット:
@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”)はPOSTリクエストを送信します。 パス変数とクエリパラメータは、前に見たのと同様の方法で設定できますが、フォームデータは、クエリパラメータと同様にparam()メソッドを介して設定できます。
http://localhost:8080/spring-mvc-test/greetWithPostAndFormData
フォームデータ:
id=1;name=John%20Doe
期待される出力:
{
"id": 1,
"message": "Hello World John Doe!!!"
}
コードスニペット:
@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」として追加しました。
5. 結論
このクイックチュートリアルでは、いくつかの簡単なSpring対応の統合テストを実装しました。
また、アプリケーションのエンドポイントを呼び出す際に重要な役割を果たしたWebApplicationContextおよびMockMVCオブジェクトの作成についても説明しました。
さらに詳しく見て、パラメーターの受け渡しのバリエーションを使用してGETおよびPOST要求を送信する方法と、HTTP応答のステータス、ヘッダー、およびコンテンツを確認する方法について説明しました。
最後に、これらすべての例とコードスニペットの実装は、https://github.com/eugenp/tutorials/tree/master/spring-mvc-java.で利用できます。