1. 概要

このチュートリアルでは、Flapdoodleの組み込みMongoDBソリューションをSpring Bootと一緒に使用して、MongoDB統合テストをスムーズに実行する方法を学習します。

MongoDBは人気のあるNoSQLドキュメントデータベースです。 高いスケーラビリティ、組み込みのシャーディング、優れたコミュニティサポートのおかげで、多くの開発者は「 theNoSQLストレージ」と見なすことがよくあります。

他の永続化テクノロジーと同様に、データベースと他のアプリケーションとの統合を簡単にテストできることが重要です。 ありがたいことに、Spring Bootを使用すると、この種のテストを簡単に作成できます。

2. Mavenの依存関係

まず、BootプロジェクトのMaven親を設定しましょう。

親のおかげで各Maven依存関係のバージョンを手動で定義する必要はありません

当然、Spring Bootを使用します。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

最新のブートバージョンはここにあります。

Spring Bootの親を追加したので、バージョンを指定せずに必要な依存関係を追加できます。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

spring-boot-starter-data-mongodb は、MongoDBのSpringサポートを有効にします。

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

de.flapdoodle.embed.mongo は、統合テスト用の組み込みMongoDBを提供します。

3. EmbeddedMongoDBを使用したテスト

このセクションでは、SpringBootテストと手動テストの2つのシナリオについて説明します。

3.1. スプリングブートテスト

de.flapdoodle.embed.mongo 依存関係を追加した後、 Spring Bootは、テストの実行時に、埋め込まれたMongoDBを自動的にダウンロードして開始しようとします。

パッケージはバージョンごとに1回だけダウンロードされるため、後続のテストははるかに高速に実行されます。

この段階で、サンプルのJUnit5統合テストを開始して合格できるはずです。

@DataMongoTest
@ExtendWith(SpringExtension.class)
public class MongoDbSpringIntegrationTest {
    @DisplayName("given object to save"
        + " when save object using MongoDB template"
        + " then object is saved")
    @Test
    public void test(@Autowired MongoTemplate mongoTemplate) {
        // given
        DBObject objectToSave = BasicDBObjectBuilder.start()
            .add("key", "value")
            .get();

        // when
        mongoTemplate.save(objectToSave, "collection");

        // then
        assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
            .containsOnly("value");
    }
}

ご覧のとおり、組み込みデータベースはSpringによって自動的に開始され、コンソールにもログインする必要があります。

...Starting MongodbExampleApplicationTests on arroyo with PID 10413...

3.2. 手動構成テスト

Spring Bootは、組み込みデータベースを自動的に起動して構成し、MongoTemplateインスタンスを挿入します。 ただし、場合によっては、組み込みのMongoデータベースを手動で構成する必要があります(たとえば、特定のDBバージョンをテストする場合)。

次のスニペットは、組み込みのMongoDBインスタンスを手動で構成する方法を示しています。 これは、前のSpringテストとほぼ同じです。

class ManualEmbeddedMongoDbIntegrationTest {
    private static final String CONNECTION_STRING = "mongodb://%s:%d";

    private MongodExecutable mongodExecutable;
    private MongoTemplate mongoTemplate;

    @AfterEach
    void clean() {
        mongodExecutable.stop();
    }

    @BeforeEach
    void setup() throws Exception {
        String ip = "localhost";
        int port = 27017;

        ImmutableMongodConfig mongodConfig = MongodConfig
            .builder()
            .version(Version.Main.PRODUCTION)
            .net(new Net(ip, port, Network.localhostIsIPv6()))
            .build();

        MongodStarter starter = MongodStarter.getDefaultInstance();
        mongodExecutable = starter.prepare(mongodConfig);
        mongodExecutable.start();
        mongoTemplate = new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, ip, port)), "test");
    }

    @DisplayName("given object to save"
        + " when save object using MongoDB template"
        + " then object is saved")
    @Test
    void test() throws Exception {
        // given
        DBObject objectToSave = BasicDBObjectBuilder.start()
            .add("key", "value")
            .get();

        // when
        mongoTemplate.save(objectToSave, "collection");

        // then
        assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
            .containsOnly("value");
    }
}

手動で構成した組み込みデータベースを使用するように構成されたMongoTemplate Beanをすばやく作成し、たとえば @TestConfiguration@を作成するだけで、Springコンテナー内に登録できることに注意してください。 new MongoTemplate(MongoClients.create(connectionString、“ test”)を返すBeanメソッド。

その他の例は、Flapdoodleの公式GitHubリポジトリにあります。

3.3. ロギング

src / test / resources / application.propertes ファイルに次の2つのプロパティを追加することで、統合テストの実行時にMongoDBのログメッセージを構成できます。

logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb

たとえば、ロギングを無効にするには、値をoffに設定するだけです。

logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off

3.4. 本番環境での実際のデータベースの使用

test を使用してde.flapdoodle.embed.mongo依存関係を追加したため、本番環境で実行するときに組み込みデータベースを無効にする必要はありません。 MongoDB接続の詳細(ホストやポートなど)を指定するだけで、準備は完了です。

テスト以外で組み込みDBを使用するには、アクティブなプロファイルに応じて適切な MongoClient (組み込みまたは本番)を登録するSpringプロファイルを使用できます。

また、本番依存のスコープを runtimeに変更する必要があります。

4. 埋め込まれたテストの論争

組み込みデータベースを使用することは、最初は素晴らしいアイデアのように思えるかもしれません。 実際、アプリケーションが次のような領域で正しく動作するかどうかをテストする場合は、これは良いアプローチです。

  • オブジェクト<->ドキュメントマッピング構成
  • カスタム永続性ライフサイクルイベントリスナー( AbstractMongoEventListener を参照)
  • 永続化レイヤーと直接連携するコードのロジック

残念ながら、組み込みサーバーの使用は、「完全統合テスト」とは見なされません。 Flapdoodleの組み込みMongoDBは、公式のMongoDB製品ではありません。 したがって、本番環境とまったく同じように動作するかどうかはわかりません。

本番環境にできるだけ近い環境で通信テストを実行する場合は、Dockerなどの環境コンテナーを使用することをお勧めします。

Dockerの詳細については、以前の記事こちらをご覧ください。

5. 結論

Spring Bootを使用すると、適切なドキュメントマッピングとデータベース統合を検証するテストを非常に簡単に実行できます。 適切なMaven依存関係を追加することで、SpringBoot統合テストでMongoDBコンポーネントをすぐに使用できるようになります。

組み込みのMongoDBサーバーは、「実際の」サーバーの代わりとは見なされないことを覚えておく必要があります。

すべての例の完全なソースコードは、GitHubから入手できます。