知識庫 / Spring / Spring Boot RSS 訂閱

Spring Boot 集成測試與嵌入式 MongoDB

NoSQL,Spring Boot,Spring Data,Testing
HongKong
7
01:44 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將學習如何使用 Flapdoodle 的嵌入式 MongoDB 解決方案與 Spring Boot 協同工作,以便順利運行 MongoDB 集成測試。

MongoDB 是一種流行的 NoSQL 文檔數據庫。 憑藉其高可擴展性、內置分片和卓越的社區支持,它通常被認為是“NoSQL 存儲” ,由許多開發人員所認為。

與任何其他持久化技術一樣,能夠輕鬆地將數據庫集成測試與我們的應用程序的其餘部分是至關重要的。 幸運的是,Spring Boot 允許我們輕鬆編寫此類測試。

2. Maven 依賴項

首先,我們為我們的 Boot 項目設置 Maven 父項目。

由於父項目,我們無需手動為每個 Maven 依賴項定義版本

我們將自然地使用 Spring Boot:

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

您可以在 這裏找到最新版本的 Boot。

由於我們添加了 Spring Boot 父模塊,因此我們可以添加所需的依賴項,而無需指定它們的版本。

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

spring-boot-starter-data-mongodb 將啓用 Spring 對 MongoDB 的支持:

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

de.flapdoodle.embed.mongo 提供嵌入式 MongoDB 用於集成測試。

3. 使用嵌入式 MongoDB 進行測試

本節涵蓋兩個場景:Spring Boot 測試和手動測試。

3.1. Spring Boot 測試

當運行測試時,de.flapdoodle.embed.mongo 依賴項被添加後,Spring Boot 將會自動嘗試下載並啓動嵌入式 MongoDB

軟件包僅在每個版本中下載一次,以便後續測試運行速度更快。

在此階段,我們應該能夠啓動並通過示例 JUnit 5 集成測試:

@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 實例。然而,有時我們可能需要手動配置嵌入式 MongoDB 數據庫(例如,在測試特定數據庫版本時)。

以下代碼片段展示瞭如何手動配置嵌入式 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@Bean 方法的 Bean,將其註冊到 Spring 容器中,從而創建 new MongoTemplate(MongoClients.create(connectionString, “test”)

更多示例可以在官方 Flapdoodle 的 GitHub 倉庫 中找到。

3.3. 日誌記錄

可以通過在 src/test/resources/application.properties 文件中添加以下兩個屬性來配置 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. 在生產環境中使用真實數據庫

由於我們通過使用 <scope>test</scope> 添加了 <em>de.flapdoodle.embed.mongo</em> 依賴項,因此在生產環境中無需禁用嵌入式數據庫。我們只需要指定 MongoDB 連接信息(例如主機和端口),即可正常運行。

要在測試之外使用嵌入式數據庫,可以使用 Spring 配置文件,該配置會根據活動配置文件註冊正確的 <em>MongoClient</em>(嵌入式或生產)。

我們還需要將生產依賴項的範圍更改為 <em>&lt;scope&gt;runtime&lt;/scope&gt;</em>。

4. 嵌入式測試爭議

使用嵌入式數據庫在初期看起來可能是一個不錯的選擇。事實上,當我們需要測試應用程序在諸如以下領域中的行為是否正確時,這是一種良好的方法:

  • 對象與文檔映射配置
  • 自定義持久化生命週期事件監聽器(參考 AbstractMongoEventListener
  • 直接與持久化層交互的代碼邏輯

不幸的是,使用嵌入式服務器不能被認為是“完整集成測試”。Flapdoodle 的嵌入式 MongoDB 不是官方 MongoDB 產品。因此,我們無法確定它在生產環境中是否表現出完全相同的方式。

如果我們想要在儘可能接近生產環境的條件下運行通信測試,那麼使用像 Docker 這樣的環境容器將是一個更好的解決方案。

要了解更多關於 Docker 的信息,請閲讀我們之前的文章在此處。

5. 結論

Spring Boot 使驗證適當文檔映射和數據庫集成而測試變得極其簡單。通過添加正確的 Maven 依賴項,我們能夠立即在 Spring Boot 集成測試中使用 MongoDB 組件。

我們需要記住的是,嵌入式 MongoDB 服務器不能被視為“真實”服務器的替代品

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.