Spring Bootユニットテストと統合テストの詳細な解を実現します。
本教程で提供したツールをどのように使うかを学び、Spring Boot環境でセルテストと統合テストを作成します。
1.概要
本論文では、ユニットテストをどのように作成するかを知り、Spring Boot環境に集積する。インターネットでこのテーマに関する教程を大量に見つけることができますが、一つのページで必要なすべての情報を見つけるのは難しいです。初期開発者はユニットテストと統合テストの概念を混同していることがよく分かります。特にSpring生態系について話しています。異なる注釈の使い分けを説明してみます。
2.ユニットテストvs.統合テスト
ウィキペディアはユニットテストということです。
コンピュータプログラミングでは、ユニットテストは、ソースコードの単一のユニット、1つまたは複数のコンピュータプログラムモジュールのセット、および関連する制御データ、使用プロセス、および操作プロセスをテストして、それらが適切に使用されるかどうかを判定するソフトウェアテスト方法である。
統合テスト:
統合テスト(統合テストと呼ばれる場合もあります。I&Tと略されます。)はソフトウェアテストの段階です。この段階では、各ソフトウェアモジュールを組み合わせてテストを行います。
簡単に言えば、私たちはユニットテストをする時、コードユニットをテストしただけです。毎回一つの方法だけをテストして、テストコンポーネントと相互作用する他のすべてのコンポーネントを含みません。
一方、統合テストでは、各コンポーネント間の統合をテストします。セルテストのために、これらのコンポーネントの挙動は必要とされるものと一致することが分かりましたが、それらがどうやって一緒に働くかは分かりません。これは集積テストの役割です。
3.Javaユニットテスト
すべてのJava開発者は、JUnitが実行ユニットテストのメインフレームであることを知っています。期待を断言するために多くの注釈が提供されています。
Hamcrestはソフトウェアテストのための付加的な枠組みです。Hamcrestは既存のmatcherクラスを使ってコード中の条件をチェックすることができます。またカスタムmatcherによって実現されます。JUnitでHamcrest matcherを使うには、
ここでは、この2つのフレームを使った簡単なテストが見られます。
簡単なプログラムを書きましょう。その目的は漫画のために基本的な検索エンジンを提供することです。
4.1.Maven依存
まず、私達の工程に依存するいくつかの追加が必要です。
私達のモデルはとても簡単です。二つの種類だけがあります。MangaとMangaResoultです。
4.2.1.Manga類
Mangaクラスは、システムが検索したMangaの例を示しています。Lombookを使ってサンプルコードを減らす。
MangaResult類はManga Listを含めた包装類です。
このServiceを実現するために、Jikan Moeによって提供される無料のAPIインターフェースを使用します。
Restit TemplateはAPIをREST呼び出しを開始するためのSpringクラスです。
次のステップは、二つのエンドポイントが暴露されたREST Controllerを書くことであり、一つは同期であり、一つは非同期であり、それはテストの目的にのみ使用される。このControllerは上で定義されたServiceを使用しています。
Spring Bootは、テストを簡単にするための強力なクラスを提供します。
Spring Bootに基づいて動作するテストクラスにこの注釈を指定することができます。
従来のSpring TestContect Fraamewark以外に、以下の機能も提供されています。@Contect Configration(loader=...)に特別な声明がない場合は、Spring BootContact LoaderをデフォルトのContect Loaderとして使用する。 は、ネストされた@Configrationを使用せずに関連クラスを明示せずに指定した場合、@Spring BootConfigrationを自動的に検索します。 により、Propertiesを使用して、Evironment属性を定義することができます。 は、定義されたまたはランダムポート上で完全に動作するWebサーバを起動する機能を含む、異なるWeb環境モードをサポートする。 は、Webサーバ上で完全に実行されるWebテストで使用するために、TestRect Templateおよび/またはWebTest Client Beanを登録する。 ここでは二つのコンポーネントしかテストが必要です。MangaServiceとMangaController
5.1.MangaServiceのユニットテストを行う
MangaServiceをテストするためには、外部のコンポーネントから分離する必要があります。この例では、外部のコンポーネントだけが必要です。RertTemplateは、遠隔APIを呼び出すためにそれを使用します。
私たちが行うべきことは、RestTemplate Beanをシミュレートし、常に固定された所定の応答で応答させることである。Spring TestはMockitoライブラリを結合して拡張しています。@MockBean注釈を通して、シミュレーションBeanを配置することができます。
MangaServiceのユニットテストで行われたように、私たちはコンポーネントを分離する必要があります。この場合には,MangaService Beanをシミュレートする必要がある。
それから、もう一つの問題があります。Controllerの部分はHttpRequestを管理するシステムの一部です。したがって、このような行為をシミュレートするシステムが必要です。完全なHTTPサーバを起動しないでください。
MockMvcは、この操作を行うSpring類です。これは異なる方法で設定できます。 Standarlone Contectを使用する WebAppleication Contectを使用する は、テストクラスで@Spring BootTest、@AutoConfigreMockMvcを使用することにより、Springにすべてのコンテキストをロードさせ、自動組立 を実現する。は、自動組立 を実現するために、テストクラスで@WebMvcTest注釈を使用してWeb層コンテキストをロードさせる。
非同期テストでは、まずサービスを呼び出して、async Displatch方法を起動して非同期挙動をシミュレートしなければならない。
6.Spring Bootアプリケーションの集積テスト
統合試験については、下流の通信を提供して、私たちの主要なコンポーネントを確認したいです。
6.1.Manga Serviceを統合テストする
このテストもとても簡単です。私たちは何もシミュレーションする必要がありません。目的はリモートManga APIを呼び出すことです。
このテストはセルテストとよく似ていますが、このケースではMangaServiceのシミュレーションは不要です。
Spring Boot環境におけるセルテストと集積テストの主な違いを知りました。Hamcrestのように試験編纂を簡略化するための枠組みを理解しました。もちろん、私の@Spring BootTestにすべてのコードを見つけることもできます。
GitHub倉庫
作者:Marco Giglione
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
1.概要
本論文では、ユニットテストをどのように作成するかを知り、Spring Boot環境に集積する。インターネットでこのテーマに関する教程を大量に見つけることができますが、一つのページで必要なすべての情報を見つけるのは難しいです。初期開発者はユニットテストと統合テストの概念を混同していることがよく分かります。特にSpring生態系について話しています。異なる注釈の使い分けを説明してみます。
2.ユニットテストvs.統合テスト
ウィキペディアはユニットテストということです。
コンピュータプログラミングでは、ユニットテストは、ソースコードの単一のユニット、1つまたは複数のコンピュータプログラムモジュールのセット、および関連する制御データ、使用プロセス、および操作プロセスをテストして、それらが適切に使用されるかどうかを判定するソフトウェアテスト方法である。
統合テスト:
統合テスト(統合テストと呼ばれる場合もあります。I&Tと略されます。)はソフトウェアテストの段階です。この段階では、各ソフトウェアモジュールを組み合わせてテストを行います。
簡単に言えば、私たちはユニットテストをする時、コードユニットをテストしただけです。毎回一つの方法だけをテストして、テストコンポーネントと相互作用する他のすべてのコンポーネントを含みません。
一方、統合テストでは、各コンポーネント間の統合をテストします。セルテストのために、これらのコンポーネントの挙動は必要とされるものと一致することが分かりましたが、それらがどうやって一緒に働くかは分かりません。これは集積テストの役割です。
3.Javaユニットテスト
すべてのJava開発者は、JUnitが実行ユニットテストのメインフレームであることを知っています。期待を断言するために多くの注釈が提供されています。
Hamcrestはソフトウェアテストのための付加的な枠組みです。Hamcrestは既存のmatcherクラスを使ってコード中の条件をチェックすることができます。またカスタムmatcherによって実現されます。JUnitでHamcrest matcherを使うには、
assertThat
文を使って、あと一つまたは複数のmatcherを使わなければなりません。ここでは、この2つのフレームを使った簡単なテストが見られます。
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.both;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;
public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals() {
assertEquals("failure - strings are not equal", "text", "text");
}
@Test
public void testAssertFalse() {
assertFalse("failure - should be false", false);
}
@Test
public void testAssertNotNull() {
assertNotNull("should not be null", new Object());
}
@Test
public void testAssertNotSame() {
assertNotSame("should not be same Object", new Object(), new Object());
}
@Test
public void testAssertNull() {
assertNull("should be null", null);
}
@Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
assertSame("should be same", aNumber, aNumber);
}
// JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
assertThat("albumen", both(containsString("a")).and(containsString("b")));
}
@Test
public void testAssertThatHasItems() {
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
}
@Test
public void testAssertThatEveryItemContainsString() {
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
}
// Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers() {
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
@Test
public void testAssertTrue() {
assertTrue("failure - should be true", true);
}
}
4.私たちのケースを紹介します。簡単なプログラムを書きましょう。その目的は漫画のために基本的な検索エンジンを提供することです。
4.1.Maven依存
まず、私達の工程に依存するいくつかの追加が必要です。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
4.2.Modelを定義する私達のモデルはとても簡単です。二つの種類だけがあります。MangaとMangaResoultです。
4.2.1.Manga類
Mangaクラスは、システムが検索したMangaの例を示しています。Lombookを使ってサンプルコードを減らす。
package com.mgiglione.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
public class Manga {
private String title;
private String description;
private Integer volumes;
private Double score;
}
4.2.2.MangaResoultMangaResult類はManga Listを含めた包装類です。
package com.mgiglione.model;
import java.util.List;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter @Setter @NoArgsConstructor
public class MangaResult {
private List<Manga> result;
}
4.3.Serviceを実現するこのServiceを実現するために、Jikan Moeによって提供される無料のAPIインターフェースを使用します。
Restit TemplateはAPIをREST呼び出しを開始するためのSpringクラスです。
package com.mgiglione.service;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.mgiglione.model.Manga;
import com.mgiglione.model.MangaResult;
@Service
public class MangaService {
Logger logger = LoggerFactory.getLogger(MangaService.class);
private static final String MANGA_SEARCH_URL="http://api.jikan.moe/search/manga/";
@Autowired
RestTemplate restTemplate;
public List<Manga> getMangasByTitle(String title) {
return restTemplate.getForEntity(MANGA_SEARCH_URL+title, MangaResult.class).getBody().getResult();
}
}
4.4.Controllerを実現する次のステップは、二つのエンドポイントが暴露されたREST Controllerを書くことであり、一つは同期であり、一つは非同期であり、それはテストの目的にのみ使用される。このControllerは上で定義されたServiceを使用しています。
package com.mgiglione.controller;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.mgiglione.model.Manga;
import com.mgiglione.service.MangaService;
@RestController
@RequestMapping(value = "/manga")
public class MangaController {
Logger logger = LoggerFactory.getLogger(MangaController.class);
@Autowired
private MangaService mangaService;
@RequestMapping(value = "/async/{title}", method = RequestMethod.GET)
@Async
public CompletableFuture<List<Manga>> searchASync(@PathVariable(name = "title") String title) {
return CompletableFuture.completedFuture(mangaService.getMangasByTitle(title));
}
@RequestMapping(value = "/sync/{title}", method = RequestMethod.GET)
public @ResponseBody <List<Manga>> searchSync(@PathVariable(name = "title") String title) {
return mangaService.getMangasByTitle(title);
}
}
4.5.システムの起動とテスト
mvn spring-boot:run
次に、Let's try it:
curl http://localhost:8080/manga/async/ken
curl http://localhost:8080/manga/sync/ken
出力例:
{
"title":"Rurouni Kenshin: Meiji Kenkaku Romantan",
"description":"Ten years have passed since the end of Bakumatsu, an era of war that saw the uprising of citizens against the Tokugawa shogunate. The revolutionaries wanted to create a time of peace, and a thriving c...",
"volumes":28,
"score":8.69
},
{
"title":"Sun-Ken Rock",
"description":"The story revolves around Ken, a man from an upper-class family that was orphaned young due to his family's involvement with the Yakuza; he became a high school delinquent known for fighting. The only...",
"volumes":25,
"score":8.12
},
{
"title":"Yumekui Kenbun",
"description":"For those who suffer nightmares, help awaits at the Ginseikan Tea House, where patrons can order much more than just Darjeeling. Hiruko is a special kind of a private investigator. He's a dream eater....",
"volumes":9,
"score":7.97
}
5.Spring BootアプリケーションのユニットテストSpring Bootは、テストを簡単にするための強力なクラスを提供します。
Spring Bootに基づいて動作するテストクラスにこの注釈を指定することができます。
従来のSpring TestContect Fraamewark以外に、以下の機能も提供されています。
5.1.MangaServiceのユニットテストを行う
MangaServiceをテストするためには、外部のコンポーネントから分離する必要があります。この例では、外部のコンポーネントだけが必要です。RertTemplateは、遠隔APIを呼び出すためにそれを使用します。
私たちが行うべきことは、RestTemplate Beanをシミュレートし、常に固定された所定の応答で応答させることである。Spring TestはMockitoライブラリを結合して拡張しています。@MockBean注釈を通して、シミュレーションBeanを配置することができます。
package com.mgiglione.service.test.unit;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import com.mgiglione.model.Manga;
import com.mgiglione.model.MangaResult;
import com.mgiglione.service.MangaService;
import com.mgiglione.utils.JsonUtils;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MangaServiceUnitTest {
@Autowired
private MangaService mangaService;
// MockBean is the annotation provided by Spring that wraps mockito one
// Annotation that can be used to add mocks to a Spring ApplicationContext.
// If any existing single bean of the same type defined in the context will be replaced by the mock, if no existing bean is defined a new one will be added.
@MockBean
private RestTemplate template;
@Test
public void testGetMangasByTitle() throws IOException {
// Parsing mock file
MangaResult mRs = JsonUtils.jsonFile2Object("ken.json", MangaResult.class);
// Mocking remote service
when(template.getForEntity(any(String.class), any(Class.class))).thenReturn(new ResponseEntity(mRs, HttpStatus.OK));
// I search for goku but system will use mocked response containing only ken, so I can check that mock is used.
List<Manga> mangasByTitle = mangaService.getMangasByTitle("goku");
assertThat(mangasByTitle).isNotNull()
.isNotEmpty()
.allMatch(p -> p.getTitle()
.toLowerCase()
.contains("ken"));
}
}
5.2.Manga Controllerに対してユニットテストを行うMangaServiceのユニットテストで行われたように、私たちはコンポーネントを分離する必要があります。この場合には,MangaService Beanをシミュレートする必要がある。
それから、もう一つの問題があります。Controllerの部分はHttpRequestを管理するシステムの一部です。したがって、このような行為をシミュレートするシステムが必要です。完全なHTTPサーバを起動しないでください。
MockMvcは、この操作を行うSpring類です。これは異なる方法で設定できます。
package com.mgiglione.service.test.unit;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.context.WebApplicationContext;
import com.mgiglione.controller.MangaController;
import com.mgiglione.model.Manga;
import com.mgiglione.service.MangaService;
@SpringBootTest
@RunWith(SpringRunner.class)
public class MangaControllerUnitTest {
MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Autowired
MangaController mangaController;
@MockBean
MangaService mangaService;
/**
* List of samples mangas
*/
private List<Manga> mangas;
@Before
public void setup() throws Exception {
this.mockMvc = standaloneSetup(this.mangaController).build();// Standalone context
// mockMvc = MockMvcBuilders.webAppContextSetup(wac)
// .build();
Manga manga1 = Manga.builder()
.title("Hokuto no ken")
.description("The year is 199X. The Earth has been devastated by nuclear war...")
.build();
Manga manga2 = Manga.builder()
.title("Yumekui Kenbun")
.description("For those who suffer nightmares, help awaits at the Ginseikan Tea House, where patrons can order much more than just Darjeeling. Hiruko is a special kind of a private investigator. He's a dream eater....")
.build();
mangas = new ArrayList<>();
mangas.add(manga1);
mangas.add(manga2);
}
@Test
public void testSearchSync() throws Exception {
// Mocking service
when(mangaService.getMangasByTitle(any(String.class))).thenReturn(mangas);
mockMvc.perform(get("/manga/sync/ken").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", is("Hokuto no ken")))
.andExpect(jsonPath("$[1].title", is("Yumekui Kenbun")));
}
@Test
public void testSearchASync() throws Exception {
// Mocking service
when(mangaService.getMangasByTitle(any(String.class))).thenReturn(mangas);
MvcResult result = mockMvc.perform(get("/manga/async/ken").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(request().asyncStarted())
.andDo(print())
// .andExpect(status().is2xxSuccessful()).andReturn();
.andReturn();
// result.getRequest().getAsyncContext().setTimeout(10000);
mockMvc.perform(asyncDispatch(result))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", is("Hokuto no ken")));
}
}
コードで見たように、最初のソリューションを選択するのは、一番軽い量の一つであり、Springコンテキストでロードされたオブジェクトに対してより良い管理ができます。非同期テストでは、まずサービスを呼び出して、async Displatch方法を起動して非同期挙動をシミュレートしなければならない。
6.Spring Bootアプリケーションの集積テスト
統合試験については、下流の通信を提供して、私たちの主要なコンポーネントを確認したいです。
6.1.Manga Serviceを統合テストする
このテストもとても簡単です。私たちは何もシミュレーションする必要がありません。目的はリモートManga APIを呼び出すことです。
package com.mgiglione.service.test.integration;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.mgiglione.model.Manga;
import com.mgiglione.service.MangaService;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MangaServiceIntegrationTest {
@Autowired
private MangaService mangaService;
@Test
public void testGetMangasByTitle() {
List<Manga> mangasByTitle = mangaService.getMangasByTitle("ken");
assertThat(mangasByTitle).isNotNull().isNotEmpty();
}
}
6.2.Manga Controllerを統合テストするこのテストはセルテストとよく似ていますが、このケースではMangaServiceのシミュレーションは不要です。
package com.mgiglione.service.test.integration;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.context.WebApplicationContext;
import com.mgiglione.controller.MangaController;
@SpringBootTest
@RunWith(SpringRunner.class)
public class MangaControllerIntegrationTest {
// @Autowired
MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Autowired
MangaController mangaController;
@Before
public void setup() throws Exception {
this.mockMvc = standaloneSetup(this.mangaController).build();// Standalone context
// mockMvc = MockMvcBuilders.webAppContextSetup(wac)
// .build();
}
@Test
public void testSearchSync() throws Exception {
mockMvc.perform(get("/manga/sync/ken").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*.title", hasItem(is("Hokuto no Ken"))));
}
@Test
public void testSearchASync() throws Exception {
MvcResult result = mockMvc.perform(get("/manga/async/ken").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(request().asyncStarted())
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(result))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*.title", hasItem(is("Hokuto no Ken"))));
}
}
7.結論Spring Boot環境におけるセルテストと集積テストの主な違いを知りました。Hamcrestのように試験編纂を簡略化するための枠組みを理解しました。もちろん、私の@Spring BootTestにすべてのコードを見つけることもできます。
GitHub倉庫
作者:Marco Giglione
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。