Overview
Testcontainers 是一个Java库,它使用Docker容器来简化集成测试。它会创建在测试期间运行的临时数据库实例,并在测试完成时自动将其删除。
本教程向您展示如何在标准Java和 Spring Boot 应用程序中将测试容器与MongoDB结合使用。
集成测试和测试容器
集成测试检查应用程序的不同部分如何协同工作。与验证单段代码的单元测试不同,集成测试会验证您的代码是否能与数据库或 API 等外部系统正确交互。
Testcontainers 在运行测试时执行以下步骤:
测试之前:创建容器、加载数据库并创建集合
测试期间:运行测试代码
测试后:删除容器并释放资源
使用测试容器的测试在任何计算机和任何操作系统上都以相同的方式运行,并且每个测试都使用自己的数据库实例。还可以根据需要在不同数据库版本之间进行切换。
先决条件
开始之前,请安装以下内容:
Java版本22 。要下载,请访问 Oracle网站。
Maven 版本3.9.6 。要下载,请访问 Maven网站。
Docker版本26.0.0 。要下载,请访问Docker网站。
您还必须将以下依赖项添加到应用程序的 pom.xml文件中:
<dependencyManagement> <dependencies> <!-- MongoDB Java Driver BOM --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-bom</artifactId> <type>pom</type> <scope>import</scope> </dependency> <!-- Testcontainers BOM --> <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers-bom</artifactId> <type>pom</type> <scope>import</scope> </dependency> <!-- JUnit BOM --> <dependency> <groupId>org.junit</groupId> <artifactId>junit-bom</artifactId> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
将测试容器与Java结合使用
以下示例测试查找 IMDb 评级高于7.0 的电影的查询。要查看完整代码,请参阅 GitHub存储库。
添加测试数据
以下代码连接到容器并添加示例电影:
public void setup() { String uri = mongoDBContainer.getConnectionString(); mongoClient = MongoClients.create(uri); database = mongoClient.getDatabase("testdb"); collection = database.getCollection("testCollection"); // Insert sample data Document doc1 = new Document("title", "Inception").append("imdb", new Document("rating", 8.8)); Document doc2 = new Document("title", "The Room").append("imdb", new Document("rating", 3.7)); Document doc3 = new Document("title", "The Dark Knight").append("imdb", new Document("rating", 9.0)); collection.insertMany(List.of(doc1, doc2, doc3)); }
编写测试
以下代码对 imdb.rating字段值大于 7 的电影运行查询并检查结果:
void testMoviesWithHighRating() { List<Document> resultDocuments = new ArrayList<>(); try (MongoCursor<Document> cursor = collection.find(Filters.gt("imdb.rating", 7)) .projection(new Document("title", 1).append("_id", 0)) .iterator()) { while (cursor.hasNext()) { Document doc = cursor.next(); System.out.println(doc.toJson()); resultDocuments.add(doc); } } assertEquals(2, resultDocuments.size()); for (Document doc : resultDocuments) { assertTrue(doc.containsKey("title")); assertFalse(doc.containsKey("_id")); } }
此测试验证以下内容:
查询正好返回 2 个文档
每个文档都有一个
title字段每个文档均不包含
_id字段
将测试容器与 Spring Boot 结合使用
以下示例使用 Spring Boot MongoDB聚合存储存储库中的代码来测试 findAll()方法。
配置 Spring Boot
以下代码将 Spring Boot 配置为使用测试数据库:
static void setProperties(DynamicPropertyRegistry registry) { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); registry.add("spring.data.mongodb.database", () -> "testdb"); } public static void setUpAll() { String mongoUri = mongoDBContainer.getConnectionString(); mongoClient = MongoClients.create(mongoUri); } public void setUp() { salesRepository.save(createMockSales()); } private Sales createMockSales() { Item item1 = new Item("Item1", Arrays.asList("Tag1", "Tag2"), new BigDecimal("19.99"), 2); Item item2 = new Item("Item2", Arrays.asList("Tag3", "Tag4"), new BigDecimal("29.99"), 1); List<Item> items = Arrays.asList(item1, item2); Customer customer = new Customer("Male", 30, "customer@example.com", 5); return new Sales(new ObjectId(), new Date(), items, "Store1", customer, true, "Online"); }
编写测试
以下代码测试 findAll() 方法:
public void testFindAll() { List<Sales> salesList = salesRepository.findAll(); assertThat(salesList).isNotEmpty(); assertThat(salesList.size()).isEqualTo(1); Sales sales = salesList.get(0); assertThat(sales.getStoreLocation()).isEqualTo("Store1"); assertThat(sales.getCustomer().getEmail()).isEqualTo("customer@example.com"); assertThat(sales.getItems()).hasSize(2); }
此测试验证以下内容:
查询正好返回 2 个文档
每个文档都有一个
title字段每个文档均不包含
_id字段