我很惊讶到目前为止没有人建议使用
fakemongo。它可以很好地模拟Mongo客户端,所有内容都在同一个JVM上运行,并且具有强大的集成测试功能,从技术上讲更接近于真正的"单元测试",因为不存在外部系统交互。这就像使用嵌入式H2来对SQL代码进行单元测试。
在测试Spring上下文中考虑以下配置,我非常满意在端到端方式中测试数据库集成代码时使用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 {
JobParameters jobParameters = new JobParametersBuilder()
.addString("studyId", "TSDR1326")
.addString("execId", UUID.randomUUID().toString())
.toJobParameters();
final JobExecution res = jobLauncherTestUtils.launchJob(jobParameters);
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)。