我很惊讶到目前为止没有人建议使用fakemongo 。它很好地模拟了 mongo 客户端,并且都运行在带有测试的同一个 JVM 上——因此集成测试变得健壮,并且在技术上更接近真正的“单元测试”,因为没有发生外部系统交互。这就像使用嵌入式 H2 对您的 SQL 代码进行单元测试。我很高兴在以端到端方式测试数据库集成代码的单元测试中使用 fakemongo。在测试弹簧上下文中考虑这个配置:
@Configuration
@Slf4j
public class FongoConfig extends AbstractMongoConfiguration {
@Override
public String getDatabaseName() {
return "mongo-test";
}
@Override
@Bean
public Mongo mongo() throws Exception {
log.info("Creating Fake Mongo instance");
return new Fongo("mongo-test").getMongo();
}
@Bean
@Override
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), getDatabaseName());
}
}
有了这个,你可以测试你在 spring 上下文中使用 MongoTemplate 的代码,并结合nosql-unit、jsonunit等,你可以获得涵盖 mongo 查询代码的强大单元测试。
@Test
@UsingDataSet(locations = {"/TSDR1326-data/TSDR1326-subject.json"}, loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
@DatabaseSetup({"/TSDR1326-data/dbunit-TSDR1326.xml"})
public void shouldCleanUploadSubjectCollection() throws Exception {
//given
JobParameters jobParameters = new JobParametersBuilder()
.addString("studyId", "TSDR1326")
.addString("execId", UUID.randomUUID().toString())
.toJobParameters();
//when
//next line runs a Spring Batch ETL process loading data from SQL DB(H2) into Mongo
final JobExecution res = jobLauncherTestUtils.launchJob(jobParameters);
//then
assertThat(res.getExitStatus()).isEqualTo(ExitStatus.COMPLETED);
final String resultJson = mongoTemplate.find(new Query().with(new Sort(Sort.Direction.ASC, "topLevel.subjectId.value")),
DBObject.class, "subject").toString();
assertThatJson(resultJson).isArray().ofLength(3);
assertThatDateNode(resultJson, "[0].topLevel.timestamp.value").isEqualTo(res.getStartTime());
assertThatNode(resultJson, "[0].topLevel.subjectECode.value").isStringEqualTo("E01");
assertThatDateNode(resultJson, "[0].topLevel.subjectECode.timestamp").isEqualTo(res.getStartTime());
... etc
}
我使用 fakemongo 没有问题 mongo 3.4 驱动程序,社区真的很接近发布支持 3.6 驱动程序的版本(https://github.com/fakemongo/fongo/issues/316)。