2016-06-12 9 views
1

Вопрос: Есть ли способ изменить конфигурацию для (Flapdoodle) встроенного монго, чтобы я мог гарантировать, что записи произойдут до чтения? Обратите внимание, что вопрос касается реализации Flapdoodle, а не MongoDB в целом. Я только хочу применить это в тесте и в config (если возможно), а не проходить через все мои операции Mongo и задавать проблемы с записью во всем мире.Как установить WriteConcern глобально для встроенных mongo (flapdoodle) для исправления ошибок прерывистого теста

Подробности

Я использую Spring + встроенный Монго в моей тестовой среде. 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); 
} 

В этом классе его довольно стандартный, только после примеров чепухи в.

95% времени это отлично работает, все мои тесты проходят. С перерывами некоторые случайные тесты терпят неудачу, например. когда я делаю что-то вроде этого:

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

Все customMethodPushToList делает, толкая строку в списке в User записи в базе данных. Здесь ничего особенного. Однако 5% времени, когда тест терпит неудачу.

Заранее спасибо.

EDIT

После ответа от плаката, я создал MongoClientOperations вручную:

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

До сих пор так хорошо ...

+0

Вы используете обманный монго или настоящий экземпляр манго для тестирования? Я столкнулся с проблемой с манным монго, который использовал реальный экземпляр monogo. благодарит заранее. – devanathan

+0

@devanathan no не было другого экземпляра Mongo –

ответ

1

Я думаю, что вам нужно использовать после того, как вы получаете DB (с getDatabase()) сWriteConcern(): http://api.mongodb.com/java/3.0/com/mongodb/async/client/MongoDatabase.html#withWriteConcern-com.mongodb.WriteConcern-

и использование ПРИЗНАН: http://api.mongodb.com/java/3.0/com/mongodb/WriteConcern.html#ACKNOWLEDGED

использовать также withReadPreference() http://api.mongodb.com/java/3.0/com/mongodb/async/client/MongoDatabase.html#withReadPreference-com.mongodb.ReadPreference-

и использовать первичные(): http://api.mongodb.com/java/3.0/com/mongodb/ReadPreference.html#primary--

Это сделает поведение столь тривиален, как это может быть.

+0

Спасибо, однако его непонятно, как я получаю ссылку на сам БД из 'TestConfig'?«MongoClientOptions» кажется неизменным, в противном случае имеет параметр «WriteConcern» –

+1

Вместо автоустановки MongoClientOptions я поместил «MongoClientOptions mongoClientOptions = MongoClientOptions.builder(). WriteConcern (WriteConcern.ACKNOWLEDGED) .build();' –

+1

@ user2393012 Если вы все еще хотите использовать '@ Autowired', вы можете использовать метод с аннотацией @ @ Bean, который создает« MongoClientOptions ». – selalerer