1. 개요
이 예제에서는 Spring Boot와 함께 Flapdoodle의 임베디드 MongoDB 솔루션을 사용하여 MongoDB 통합 테스트를 원활하게 실행하는 방법을 배웁니다.
MongoDB는 대중적인 NoSQL 문서 데이터베이스 입니다. 높은 확장성, 내장된 샤딩 및 뛰어난 커뮤니티 지원 덕분 에 많은 개발자들이 종종 "NoSQL 스토리지"로 간주 합니다 .
다른 지속성 기술과 마찬가지로 애플리케이션의 나머지 부분과 데이터베이스 통합을 쉽게 테스트할 수 있는 것이 중요합니다 . 고맙게도 Spring Boot를 사용하면 이러한 종류의 테스트를 쉽게 작성할 수 있습니다.
2. 메이븐 의존성
먼저 Boot 프로젝트의 Maven 부모를 설정하겠습니다.
부모 덕분 에 각 Maven 의존성에 대한 버전을 수동으로 정의할 필요가 없습니다 .
자연스럽게 Spring Boot를 사용할 것입니다.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</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. Embedded MongoDB를 사용한 테스트
이 섹션에서는 Spring Boot 테스트와 수동 테스트의 두 가지 시나리오를 다룹니다.
3.1. 스프링 부트 테스트
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 인스턴스를 주입합니다. 그러나 때로는 임베디드 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 빈 을 신속하게 생성할 수 있으며 예 를 들어 새로운 MongoTemplate ( MongoClients.create (connectionString, “ 테스트”) .
더 많은 예제는 공식 Flapdoodle의 GitHub 저장소 에서 찾을 수 있습니다 .
3.3. 벌채 반출
다음 두 속성을 src/test/resources/application.propertes 파일에 추가하여 통합 테스트를 실행할 때 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> 를 사용하여 de.flapdoodle.embed.mongo 의존성을 추가 했으므로 프로덕션에서 실행할 때 임베디드 데이터베이스를 비활성화할 필요가 없습니다 . MongoDB 연결 세부 정보(예: 호스트 및 포트)를 지정하기만 하면 됩니다.
테스트 외부에서 임베디드 DB를 사용하려면 활성 프로파일에 따라 올바른 MongoClient (임베디드 또는 프로덕션)를 등록하는 Spring 프로파일을 사용할 수 있습니다.
또한 프로덕션 의존성의 범위를 <scope>runtime</scope> 으로 변경해야 합니다 .
4. 임베디드 테스팅 논란
임베디드 데이터베이스를 사용하는 것은 처음에는 좋은 생각처럼 보일 수 있습니다. 실제로 다음과 같은 영역에서 응용 프로그램이 올바르게 작동하는지 테스트하려는 경우 좋은 접근 방식입니다.
- 개체<->문서 매핑 구성
- 사용자 정의 지속성 라이프사이클 이벤트 리스너( AbstractMongoEventListener 참조 )
- 지속성 계층과 직접 작동하는 모든 코드의 논리
아쉽게도 임베디드 서버를 사용하는 것은 "전체 통합 테스트"로 간주될 수 없습니다 . Flapdoodle의 임베디드 MongoDB는 공식 MongoDB 제품이 아닙니다. 따라서 프로덕션 환경에서와 같이 정확하게 작동하는지 확신할 수 없습니다.
프로덕션과 최대한 가까운 환경에서 통신 테스트를 실행하려면 Docker와 같은 환경 컨테이너를 사용하는 것이 더 나은 솔루션입니다.
Docker에 대해 자세히 알아보려면 여기에서 이전 기사를 읽어보세요 .
5. 결론
Spring Boot를 사용하면 적절한 문서 매핑 및 데이터베이스 통합을 확인하는 테스트를 매우 간단하게 실행할 수 있습니다. 올바른 Maven 의존성을 추가하면 Spring Boot 통합 테스트에서 MongoDB 구성 요소를 즉시 사용할 수 있습니다.
임베디드 MongoDB 서버는 "실제" 서버를 대체할 수 없다는 점을 기억해야 합니다 .
모든 예제의 전체 소스 코드는 GitHub에서 사용할 수 있습니다 .