spring-boot
春のブートでのテスト
サーチ…
簡単なスプリングブートアプリケーションをテストする方法
MongoDBにユーザデータを格納するSpringブートアプリケーションのサンプルがあり、Restサービスを使ってデータを取得しています
最初にドメインクラス、つまりPOJOがあります
@Document
public class User{
@Id
private String id;
private String name;
}
Springデータに基づく対応するリポジトリMongoDB
public interface UserRepository extends MongoRepository<User, String> {
}
次に、ユーザコントローラ
@RestController
class UserController {
@Autowired
private UserRepository repository;
@RequestMapping("/users")
List<User> users() {
return repository.findAll();
}
@RequestMapping(value = "/Users/{id}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
void delete(@PathVariable("id") String id) {
repository.delete(id);
}
// more controller methods
}
最後に、Springブートアプリケーション
@SpringBootApplication
public class Application {
public static void main(String args[]){
SpringApplication.run(Application.class, args);
}
}
John Cena、The RockとTripleHHHがデータベース内の唯一の3人のユーザーであったとすると、/ usersへのリクエストは次のように応答します。
$ curl localhost:8080/users
[{"name":"John Cena","id":"1"},{"name":"The Rock","id":"2"},{"name":"TripleHHH","id":"3"}]
コードをテストするために、アプリケーションが動作することを確認します
@RunWith(SpringJUnit4ClassRunner.class) // 1
@SpringApplicationConfiguration(classes = Application.class) // 2
@WebAppConfiguration // 3
@IntegrationTest("server.port:0") // 4
public class UserControllerTest {
@Autowired // 5
UserRepository repository;
User cena;
User rock;
User tripleHHH;
@Value("${local.server.port}") // 6
int port;
@Before
public void setUp() {
// 7
cena = new User("John Cena");
rock = new User("The Rock");
tripleHHH = new User("TripleHH");
// 8
repository.deleteAll();
repository.save(Arrays.asList(cena, rock, tripleHHH));
// 9
RestAssured.port = port;
}
// 10
@Test
public void testFetchCena() {
String cenaId = cena.getId();
when().
get("/Users/{id}", cenaId).
then().
statusCode(HttpStatus.SC_OK).
body("name", Matchers.is("John Cena")).
body("id", Matchers.is(cenaId));
}
@Test
public void testFetchAll() {
when().
get("/users").
then().
statusCode(HttpStatus.SC_OK).
body("name", Matchers.hasItems("John Cena", "The Rock", "TripleHHH"));
}
@Test
public void testDeletetripleHHH() {
String tripleHHHId = tripleHHH.getId();
when()
.delete("/Users/{id}", tripleHHHId).
then().
statusCode(HttpStatus.SC_NO_CONTENT);
}
}
説明
- 他のSpringベースのテストと同様に、
SpringJUnit4ClassRunner
が必要なので、アプリケーションコンテキストが作成されます。 -
@SpringApplicationConfiguration
アノテーションは、@ContextConfiguration
で使用する必要があるアプリケーションコンテキストを指定するために使用されるという点で@ContextConfiguration
アノテーションに似ています。さらに、Springブート固有の設定やプロパティなどを読み込むためのロジックを起動します。 -
@WebAppConfiguration
は、WebApplicationContext
をテストのためにロードする必要があることをSpringに知らせるために存在しなければなりません。また、Webアプリケーションのルートへのパスを指定するための属性も提供します。 -
@IntegrationTest
は、Springブートに、組み込みWebサーバーを起動するよう指示するために使用されます。コロンまたは等号で区切られた名前と値のペアを指定することにより、任意の環境変数を上書きすることができます。この例では、"server.port:0"
はサーバーのデフォルトポート設定を上書きします。通常、サーバーは指定されたポート番号を使用し始めますが、値0は特別な意味を持ちます。 0と指定すると、Springブートはホスト環境のポートをスキャンし、使用可能なランダムなポートでサーバーを起動するように指示します。これは、開発マシン上で異なるポートを占有し、アプリケーションポートと衝突する可能性のあるビルドサーバーが異なる場合、アプリケーションが起動しない場合に便利です。第2に、異なるアプリケーションコンテキストで複数の統合テストを作成すると、テストが同時に実行されている場合にも衝突する可能性があります。 - 私たちはアプリケーションコンテキストにアクセスし、autowiringを使用してSpring Beanを注入することができます。
-
@Value("${local.server.port}”)
は、使用されている実際のポート番号に解決されます。 - 検証のために使用できるエンティティをいくつか作成します。
- MongoDBデータベースは、テストごとにクリアされ、再初期化されるので、常に既知の状態に対して検証されます。テストの順序は定義されていないので、testDeletetripleHHH()テストの後にtestFetchAll()テストを実行すると失敗します。
- 私たちは安心して正しいポートを使用するように指示します。これは、安価なサービスをテストするためのJava DSLを提供するオープンソースプロジェクトです。
- テストは、Rest Assuredを使用して実装されます。私たちはTestRestTemplateやその他のHTTPクライアントを使ってテストを実装できますが、RestDocsを使って簡潔な文書を書くことができるので、私はRest Assuredを使用します
異なるyaml [またはプロパティ]ファイルを読み込むか、いくつかのプロパティをオーバーライドする
私たちが@SpringApplicationConfiguration
を使用するときは、 application.yml
[properties]の設定を使用しますが、これは特定の状況では適切ではありません。したがって、プロパティをオーバーライドするには@TestPropertySource
アノテーションを使用できます。
@TestPropertySource(
properties = {
"spring.jpa.hibernate.ddl-auto=create-drop",
"liquibase.enabled=false"
}
)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{
// ...
}
@TestPropertySource
プロパティ属性を使用して、必要な特定のプロパティをオーバーライドできます。上記の例では、 create-drop
プロパティspring.jpa.hibernate.ddl-auto
をオーバーライドしています。そしてliquibase.enabled
をfalse
。
異なるymlファイルを読み込む
テストのために別のymlファイルを完全にロードする場合は、 @TestPropertySource
locations属性を使用できます。
@TestPropertySource(locations="classpath:test.yml")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{
// ...
}
別のオプション
オプション1:
また、別のymlファイルをロードして、 ymlファイルをtest > resource
ディレクトリに配置することもできます
オプション2:
@ActiveProfiles
アノテーションの使用
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ActiveProfiles("somename")
public class MyIntTest{
}
私たちは@ActiveProfiles
アノテーションを使用していることがわかりますし、値としてsomenameを渡しています。
application-somename.yml
というファイルを作成すると、このファイルが読み込まれます。