如何为嵌入式mongo(flapdoodle)全局设置WriteConcern以修复间歇性测试失败

时间:2016-06-12 08:52:46

标签: java spring-data-mongodb embedded-database

问题:有没有办法更改(Flapdoodle)嵌入式mongo的配置,以便我可以保证在读取之前进行写入?请注意问题是关于Flapdoodle的实现,而不是一般的MongoDB。我只想在测试和配置中应用它(如果可能的话),而不是遍历我所有的Mongo操作并在任何地方设置写入问题。

详情

我在测试环境中使用Spring + embedded mongo。 Maven依赖关系如下所示:

<dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>1.50.1</version>
        <scope>test</scope>
</dependency>

使用测试配置类:

@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
@EnableMongoRepositories(basePackages = "path.to.repos")
public class TestMongoConfig {
private static final String DESTROY_METHOD_CLOSE = "close";
private static final String DESTROY_METHOD_STOP = "stop";

private static final Logger LOGGER = LoggerFactory.getLogger(TestMongoConfig.class);

@Autowired
private MongoProperties mongoProperties;

@Autowired(required = false)
private MongoClientOptions mongoClientOptions;

@Autowired
private Environment environment;

@Bean(destroyMethod = DESTROY_METHOD_CLOSE)
public MongoClient mongo() throws IOException {
    Net net = mongodProcess().getConfig().net();
    mongoProperties.setHost(net.getServerAddress().getHostName());
    mongoProperties.setPort(net.getPort());
    return mongoProperties.createMongoClient(this.mongoClientOptions, environment);
}

@Bean(destroyMethod = DESTROY_METHOD_STOP)
public MongodProcess mongodProcess() throws IOException {
    return mongodExecutable().start();
}

@Bean(destroyMethod = DESTROY_METHOD_STOP)
public MongodExecutable mongodExecutable() throws IOException {
    return mongodStarter().prepare(mongodConfig());
}

@Bean
public IMongodConfig mongodConfig() throws IOException {
    return new MongodConfigBuilder().version(Version.Main.PRODUCTION).build();
}

@Bean
public MongodStarter mongodStarter() {
    Command command = Command.MongoD;
    IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
            .defaultsWithLogger(command, LOGGER)
            .artifactStore(new ExtractedArtifactStoreBuilder()
                    .defaults(command)
                    .download(new DownloadConfigBuilder()
                            .defaultsForCommand(command).build())
                    .executableNaming(new UserTempNaming()))
            .build();

    return MongodStarter.getInstance(runtimeConfig);
}

在该课程中它非常标准,只是遵循flapdoodle的例子。

95%的时间效果很好,我的所有测试都通过了。间歇性的一些随机测试失败,例如当我做这样的事情时:

userRepository.customMethodPushToList(user.getId(), aString);
user = userRepository.findOne(user.getId());
assertEquals(2, user.getSomeList().size());

所有customMethodPushToList正在将字符串推送到数据库中User条目中的列表。这里没什么特别的。然而,5%的时间测试失败。

认为是因为与写作有关的事情......即我已经在对象被更新之前检索了它。

提前致谢。

修改

在海报回答后,我手动创建了MongoClientOperations

MongoClientOptions mongoClientOptions = MongoClientOptions.builder().writeConcern(WriteConcern.ACKNOWLEDGED).build();

到目前为止一直很好......

1 个答案:

答案 0 :(得分:1)