I want to ensure that @Transactional annotation works so I wrote a test which save and publish article - my kafka publisher is a mock which throws an exception on any call. I want to ensure MongoDB rolls back the persisted article.
@Test
void testRollbackOnPublishFail() {
when(producer.publishArticle(any())).thenThrow(IllegalStateException.class);
ArticleDocument articleDocument = ArticleTestDataUtil.createArticleDocument();
try {
ArticleDocument publishedDocument = articleService.saveAndPublish(articleDocument);
} catch (Exception e) {
assertTrue(e instanceof IllegalStateException);
}
assertFalse(articleService.findById(articleDocument.getId()).isPresent());
}
I am using flapdoodles embedded mongo db for integration tests
testCompile "de.flapdoodle.embed:de.flapdoodle.embed.mongo:2.2.0"
This tests fails because there is no transaction / replication on default.
So activated transactions by creating MongoTransactionManager:
@Configuration
public class MongoTransactionConfig {
@Bean
public MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
}
Now my test fails because was not able to start a Session in MongoClient
com.mongodb.MongoClientException: Sessions are not supported by the MongoDB cluster to which this client is connected
at com.mongodb.MongoClient.startSession(MongoClient.java:560)
I also tried to create a custom IMongodConfig
@Bean(name = "customReplicaMongodConfig")
public IMongodConfig mongodConfig(EmbeddedMongoProperties embeddedProperties) throws IOException {
Storage storage = new Storage("/tmp", "rs0", 0);
return new MongodConfigBuilder()
.shardServer(true)
.version(Version.V4_0_2)
.net(new Net(27117, Network.localhostIsIPv6()))
.replication(storage)
.cmdOptions(new MongoCmdOptionsBuilder().useNoJournal(false).build()).build();
}
And initiate the replication:
@ConditionalOnBean(name = "customReplicaMongodConfig")
@Configuration
public class ReplicaConfig {
@Inject
private MongoClient mongoClient;
@PostConstruct
public void initiateReplicationSet() {
mongoClient.getDatabase("admin").runCommand(new Document("replSetInitiate", new Document()));
}
}
But the replSetInitiate failed with an timeout.
So my question is if it is possible to create a running replication set with embedded MongoDB to test transactional.