Unit testing with MongoDB

后端 未结 5 1081
后悔当初
后悔当初 2020-12-07 16:37

My database of choice is MongoDB. I\'m writing a data-layer API to abstract implementation details from client applications - that is, I\'m essentially providing a single pu

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-07 17:24

    I'm surprised no one advised to use fakemongo so far. It emulates mongo client pretty well, and it all runs on same JVM with tests - so integration tests become robust, and technically much more close to true "unit tests", since no foreign system interaction takes place. It's like using embedded H2 to unit test your SQL code. I was very happy using fakemongo in unit tests that test database integration code in end-to-end manner. Consider this configuration in test spring context:

    @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());
        }
    
    }
    

    With this you can test your code that uses MongoTemplate from spring context, and in combination with nosql-unit, jsonunit, etc. you get robust unit tests that cover mongo querying code.

    @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
    }
    

    I used fakemongo without problems with mongo 3.4 driver, and community is really close to release a version that supports 3.6 driver (https://github.com/fakemongo/fongo/issues/316).

提交回复
热议问题