개요
Testcontainers는 Docker 컨테이너를 사용하여 통합 테스트를 간소화하는 Java 라이브러리입니다. 테스트 중에 실행 임시 데이터베이스 인스턴스를 생성하고 테스트가 완료되면 자동으로 제거합니다.
이 튜토리얼에서는 표준 Java 및 Spring Boot 애플리케이션 모두에서 MongoDB 와 함께 Testcontainer를 사용하는 방법을 보여줍니다.
통합 테스트 및 테스트 컨테이너
통합 테스트는 애플리케이션 의 다양한 부분이 어떻게 함께 작동하는지 확인합니다. 개별 코드의 유효성을 검사하는 단위 테스트와 달리 통합 테스트는 코드가 데이터베이스나 API와 같은 외부 시스템과 올바르게 상호 작용하는지 확인합니다.
Testcontainers는 테스트를 실행 때 다음 단계를 수행합니다.
테스트 전: 컨테이너 생성하고, 데이터베이스 로드하고, 컬렉션을 생성합니다.
테스트 중: 테스트 코드 실행
테스트 후: 컨테이너 제거하고 리소스를 확보합니다.
Testcontainer를 사용하는 테스트는 모든 컴퓨터와 운영 체제에서 동일한 방식으로 실행 , 각 테스트는 자체 데이터베이스 인스턴스 사용합니다. 필요한 경우 다른 데이터베이스 버전 간에 전환할 수도 있습니다.
전제 조건
시작하기 전에 다음을 설치합니다.
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 와 함께 Testcontainers 사용
다음 예시 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필드 제외합니다.