小编典典

如何在springboot应用程序中使用嵌入式mongoDB进行junit测试?

spring-boot

我正在学习springboot,并创建了一个简单的springboot应用程序。我希望它在运行单元测试时使用嵌入式mongoDB,并在其余应用程序中使用外部mongoDB。但是,它使用外部mongoDB进行单元测试,而不是使用嵌入式mongoDB。我的POM中有以下两个依赖项。

    <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>
        <scope>test</scope>
    </dependency>

我的属性文件具有以下内容:

# MongoDB properties
mongo.db.name=person_testDB
mongo.db.url=localhost

#external Mongo url
spring.data.mongodb.uri=mongodb://localhost:27017/personDB

我有一个配置文件(MongoDBConfig.java),其中包含嵌入式MongoDB配置:

@EnableMongoRepositories
public class MongoDBConfig {

@Value("${mongo.db.url}")
private String MONGO_DB_URL;

@Value("${mongo.db.name}")
private String MONGO_DB_NAME;

@Bean
public MongoTemplate mongoTemplate() {
    MongoClient mongoClient = new MongoClient(MONGO_DB_URL);
    MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, MONGO_DB_NAME);
    return mongoTemplate;
 }
}

以下是我的PersonService.java课程:

@Service
public class PersonService  {
private static final Logger logger = LoggerFactory.getLogger(PersonService.class);      
@Autowired
MongoTemplate mongoTemplate;            
public void savePerson(Person person) {
    String name = person.getName();
    String collectionName = name.substring(0, 1);
        mongoTemplate.save(person, collectionName);
    }               
}

我对PersonsService类的单元测试如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MongoDBConfig.class})
@SpringBootTest(classes = PersonService.class)
@DataMongoTest
public class PersonServiceTest {

@Autowired
PersonService personService;    
MongodForTestsFactory factory;
MongoClient mongo;

@Before
public void setup() throws Exception {
    factory = MongodForTestsFactory.with(Version.Main.PRODUCTION);
    mongo = factory.newMongo();
}

@After
public void teardown() throws Exception {
    if (factory != null)
        factory.shutdown();
}

@Test
public void testSave(){
Person person = new Person("Bob Smith " , 25);
personService.savePerson(person);
}
}

它在外部MongoDB中正确创建了集合名称和文档名称,这不是我想要的。如何将unitTests限制为嵌入式Mongo?


阅读 896

收藏
2020-05-30

共1个答案

小编典典

一种替代方法是在测试中运行整个spring boot应用程序。在这种情况下,您的spring
boot应用程序将被自动发现,嵌入式mongoDB将由Spring Boot下载并启动。

@RunWith(SpringRunner.class)
@SpringBootTest
public class YourSpringBootApplicationTests {

08:12:14.676 INFO EmbeddedMongo:42-注意:noprealloc可能会损害许多应用程序的性能08:12:14.694
INFO EmbeddedMongo:42-2017-12-31T08:12:14.693 + 0200 I CONTROL
[initandlisten] MongoDB开始:pid = 2246 port = 52299 08:12:22.005
INFO连接:71-已打开到本地主机的连接[connectionId {localValue:2,serverValue:2}]

在您的示例中,您可以修改代码以在其他端口上启动嵌入式Mongo:

  1. 添加test / resoures / test.properties文件以覆盖application.properties中的属性
      mongo.db.name=person_testDB
  mongo.db.url=localhost
  mongo.db.port=12345
  1. 修改MongoDBConfig:添加MONGO_DB_PORT字段
      @EnableMongoRepositories
  public class MongoDBConfig {
      @Value("${mongo.db.url}")
      private String MONGO_DB_URL;

      @Value(("${mongo.db.port:27017}"))
      private int MONGO_DB_PORT;

      @Value("${mongo.db.name}")
      private String MONGO_DB_NAME;

      @Bean
      public MongoTemplate mongoTemplate() {
          MongoClient mongoClient = new MongoClient(MONGO_DB_URL, MONGO_DB_PORT);
          MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, MONGO_DB_NAME);
          return mongoTemplate;
      }
  }
  1. 修改测试类:删除@DataMongoTest批注。该注释强制启动嵌入式mongoDB实例
      static MongodExecutable mongodExecutable;

  @BeforeClass
  public static void setup() throws Exception {
      MongodStarter starter = MongodStarter.getDefaultInstance();
      String bindIp = "localhost";
      int port = 12345;
      IMongodConfig mongodConfig = new MongodConfigBuilder()
              .version(Version.Main.PRODUCTION)
              .net(new Net(bindIp, port, Network.localhostIsIPv6()))
              .build();
      mongodExecutable = null;
      try {
          mongodExecutable = starter.prepare(mongodConfig);
          mongodExecutable.start();
      } catch (Exception e){
          // log exception here
          if (mongodExecutable != null)
              mongodExecutable.stop();
      }
  }

  @AfterClass
  public static void teardown() throws Exception {
      if (mongodExecutable != null)
          mongodExecutable.stop();
  }

另一种方法是使用MongoRepository和init嵌入式Mongo作为测试@Configuration类的一部分:此处概述:如何配置嵌入式MongDB以在Spring
Boot应用程序中进行集成测试?

2020-05-30