Spring Boot 어플리케이션에서의 통합 테스트용으로 Embedded MongDB를 설정하려면 어떻게 해야 합니까?
저는 작은 REST API를 공개하고 MongoDB 인스턴스에서 데이터를 가져오는 매우 간단한 Spring Boot 어플리케이션을 가지고 있습니다.MongoDB 인스턴스에 대한 쿼리는 Spring Data 기반 저장소를 통과합니다.아래 코드의 주요 비트를 나타냅니다.
// Main application class
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
@ComponentScan
@Import(MongoConfig.class)
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
// Product repository with Spring data
public interface ProductRepository extends MongoRepository<Product, String> {
Page<Product> findAll(Pageable pageable);
Optional<Product> findByLineNumber(String lineNumber);
}
// Configuration for "live" connections
@Configuration
public class MongoConfig {
@Value("${product.mongo.host}")
private String mongoHost;
@Value("${product.mongo.port}")
private String mongoPort;
@Value("${product.mongo.database}")
private String mongoDatabase;
@Bean(name="mongoClient")
public MongoClient mongoClient() throws IOException {
return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
}
@Autowired
@Bean(name="mongoDbFactory")
public MongoDbFactory mongoDbFactory(MongoClient mongoClient) {
return new SimpleMongoDbFactory(mongoClient, mongoDatabase);
}
@Autowired
@Bean(name="mongoTemplate")
public MongoTemplate mongoTemplate(MongoClient mongoClient) {
return new MongoTemplate(mongoClient, mongoDatabase);
}
}
@Configuration
@EnableMongoRepositories
public class EmbeddedMongoConfig {
private static final String DB_NAME = "integrationTest";
private static final int DB_PORT = 12345;
private static final String DB_HOST = "localhost";
private static final String DB_COLLECTION = "products";
private MongodExecutable mongodExecutable = null;
@Bean(name="mongoClient")
public MongoClient mongoClient() throws IOException {
// Lots of calls here to de.flapdoodle.embed.mongo code base to
// create an embedded db and insert some JSON data
}
@Autowired
@Bean(name="mongoDbFactory")
public MongoDbFactory mongoDbFactory(MongoClient mongoClient) {
return new SimpleMongoDbFactory(mongoClient, DB_NAME);
}
@Autowired
@Bean(name="mongoTemplate")
public MongoTemplate mongoTemplate(MongoClient mongoClient) {
return new MongoTemplate(mongoClient, DB_NAME);
}
@PreDestroy
public void shutdownEmbeddedMongoDB() {
if (this.mongodExecutable != null) {
this.mongodExecutable.stop();
}
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestProductApplication.class)
@IntegrationTest
@WebAppConfiguration
public class WtrProductApplicationTests {
@Test
public void contextLoads() {
// Tests empty for now
}
}
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
@ComponentScan
@Import(EmbeddedMongoConfig.class)
public class TestProductApplication {
public static void main(String[] args) {
SpringApplication.run(TestProductApplication.class, args);
}
}
즉, 통합 테스트(현재는 비어 있음)를 임베디드 Mongo 인스턴스에 연결하고 "라이브" 인스턴스에 연결하는 것이 중요합니다.하지만, 그것은 효과가 없습니다.Mongo의 "라이브" 인스턴스에 연결되어 있는 테스트를 볼 수 있으며, 이 테스트를 종료하면 Mongo의 라이브 인스턴스에 연결을 시도 중이기 때문에 빌드는 실패합니다.왜 그런지 아는 사람 있어요?임베디드 인스턴스에 연결하기 위한 테스트를 받으려면 어떻게 해야 합니까?
Spring Boot 버전 1.3 이후부터EmbeddedMongoAutoConfiguration
틀에서 벗어난 수업입니다.즉, 컨피규레이션파일을 전혀 작성할 필요가 없으며 변경할 수 있는 것을 변경할 수 있습니다.
Embedded MongoDB 자동 구성이 추가되었습니다.시작하기 위해서는 de.flapdoodle.embed:de.flapdoodle.embed.mongo에 의존하기만 하면 됩니다.사용하는 Mongo 버전 등의 설정은 application.properties를 통해 제어할 수 있습니다.상세한 것에 대하여는, 메뉴얼을 참조해 주세요.(스프링 부트 릴리스 노트)
application.properties 파일에 추가해야 하는 가장 기본적이고 중요한 설정은 다음과 같습니다.spring.data.mongodb.port=0
(0은 무료에서 랜덤으로 선택되는 것을 의미합니다.)
자세한 내용은 Spring Boot Docs MongoDb를 참조하십시오.
편집: Spring Boot 1.3+에 대한 Magic Crafter의 답변을 참조하십시오.EmbeddedMongoAutoConfiguration
.
어떤 이유로든 사용할 수 없다면 계속 읽어보세요.
테스트 클래스:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
Application.class,
TestMongoConfig.class // <--- Don't forget THIS
})
public class GameRepositoryTest {
@Autowired
private GameRepository gameRepository;
@Test
public void shouldCreateGame() {
Game game = new Game(null, "Far Cry 3");
Game gameCreated = gameRepository.save(game);
assertEquals(gameCreated.getGameId(), gameCreated.getGameId());
assertEquals(game.getName(), gameCreated.getName());
}
}
간단한 MongoDB 저장소:
public interface GameRepository extends MongoRepository<Game, String> {
Game findByName(String name);
}
MongoDB 테스트 구성:
import com.mongodb.Mongo;
import com.mongodb.MongoClientOptions;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
@Configuration
public class TestMongoConfig {
@Autowired
private MongoProperties properties;
@Autowired(required = false)
private MongoClientOptions options;
@Bean(destroyMethod = "close")
public Mongo mongo(MongodProcess mongodProcess) throws IOException {
Net net = mongodProcess.getConfig().net();
properties.setHost(net.getServerAddress().getHostName());
properties.setPort(net.getPort());
return properties.createMongoClient(this.options);
}
@Bean(destroyMethod = "stop")
public MongodProcess mongodProcess(MongodExecutable mongodExecutable) throws IOException {
return mongodExecutable.start();
}
@Bean(destroyMethod = "stop")
public MongodExecutable mongodExecutable(MongodStarter mongodStarter, IMongodConfig iMongodConfig) throws IOException {
return mongodStarter.prepare(iMongodConfig);
}
@Bean
public IMongodConfig mongodConfig() throws IOException {
return new MongodConfigBuilder().version(Version.Main.PRODUCTION).build();
}
@Bean
public MongodStarter mongodStarter() {
return MongodStarter.getDefaultInstance();
}
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>1.48.0</version>
<scope>test</scope>
</dependency>
버전 1.5.7에서는 다음 항목만 사용합니다.
@RunWith(SpringRunner.class)
@DataMongoTest
public class UserRepositoryTests {
@Autowired
UserRepository repository;
@Before
public void setUp() {
User user = new User();
user.setName("test");
repository.save(user);
}
@Test
public void findByName() {
List<User> result = repository.findByName("test");
assertThat(result).hasSize(1).extracting("name").contains("test");
}
}
그리고.
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
이전 답변을 완료하겠습니다.
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>${embedded-mongo.version}</version>
</dependency>
MongoConfig(MongoConfig)
@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
다음 사항에 대해 명확하게 설명하십시오.@ComponentScan
디폴트로는
특정 패키지가 정의되지 않은 경우 이 주석이 있는 클래스의 패키지에서 검색이 수행됩니다.(@ComponentScan Javadoc)
따라서, 만약 당신이TestProductApplication
그리고.ProductApplication
구성이 모두 같은 패키지에 포함되어 있습니다.스프링에서 컴포넌트를 스캔하고 있을 가능성이 있습니다.ProductApplication
설정을 실시합니다.
또한 테스트 mongo 빈을 '테스트' 또는 '로컬' 프로파일에 넣고 테스트 클래스에서 @ActiveProfiles 주석을 사용하여 테스트/로컬 프로파일을 활성화하는 것을 권장합니다.
언급URL : https://stackoverflow.com/questions/31568351/how-do-you-configure-embedded-mongdb-for-integration-testing-in-a-spring-boot-ap
'programing' 카테고리의 다른 글
Spring Application Configuration을 찾을 수 없음: 잘못된 Spring-boot-starter-test 내용입니까? (0) | 2023.03.18 |
---|---|
AngularJS: 높이 변화를 관찰하는 더 좋은 방법 (0) | 2023.03.18 |
페이지 전체에서 키 누르기 이벤트를 청취하려면 어떻게 해야 하나요? (0) | 2023.03.18 |
UI-Router가 Angular에 있는 기본 서브스테이트로 상태 리다이렉트JS (0) | 2023.03.18 |
memcpy() 및 memmove()가 포인터의 증가보다 빠른 이유는 무엇입니까? (0) | 2023.02.04 |