Skip to content

Commit 83e4bb3

Browse files
committed
Add transaction auto-configuration to @DataMongoTest
Closes gh-20182
1 parent 52fbf47 commit 83e4bb3

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

spring-boot-project/spring-boot-test-autoconfigure/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ dependencies {
6666
testImplementation("org.aspectj:aspectjrt")
6767
testImplementation("org.aspectj:aspectjweaver")
6868
testImplementation("org.assertj:assertj-core")
69+
testImplementation("org.awaitility:awaitility")
6970
testImplementation("org.hibernate.validator:hibernate-validator")
7071
testImplementation("org.hsqldb:hsqldb")
7172
testImplementation("org.jooq:jooq")

spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoC
3737
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
3838
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
3939
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
40-
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration
40+
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
41+
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
4142

4243
# AutoConfigureDataNeo4j auto-configuration imports
4344
org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j=\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.data.mongo;
18+
19+
import java.io.IOException;
20+
import java.time.Duration;
21+
import java.util.List;
22+
23+
import com.mongodb.BasicDBList;
24+
import com.mongodb.ServerAddress;
25+
import com.mongodb.client.ClientSession;
26+
import com.mongodb.client.MongoClient;
27+
import com.mongodb.client.MongoDatabase;
28+
import com.mongodb.connection.ServerDescription;
29+
import de.flapdoodle.embed.mongo.config.IMongoCmdOptions;
30+
import de.flapdoodle.embed.mongo.config.IMongodConfig;
31+
import de.flapdoodle.embed.mongo.config.MongoCmdOptionsBuilder;
32+
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
33+
import de.flapdoodle.embed.mongo.config.Storage;
34+
import de.flapdoodle.embed.mongo.distribution.Version;
35+
import org.awaitility.Awaitility;
36+
import org.bson.Document;
37+
import org.junit.jupiter.api.Test;
38+
39+
import org.springframework.beans.factory.InitializingBean;
40+
import org.springframework.beans.factory.annotation.Autowired;
41+
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoProperties;
42+
import org.springframework.boot.test.context.TestConfiguration;
43+
import org.springframework.context.annotation.Bean;
44+
import org.springframework.data.mongodb.MongoDatabaseFactory;
45+
import org.springframework.data.mongodb.MongoTransactionManager;
46+
import org.springframework.data.mongodb.core.MongoTemplate;
47+
import org.springframework.transaction.annotation.Transactional;
48+
49+
import static org.assertj.core.api.Assertions.assertThat;
50+
51+
/**
52+
* Tests for using {@link DataMongoTest @DataMongoTest} with transactions.
53+
*
54+
* @author Andy Wilkinson
55+
*/
56+
@DataMongoTest
57+
@Transactional
58+
class TransactionalDataMongoTestIntegrationTests {
59+
60+
@Autowired
61+
private ExampleRepository exampleRepository;
62+
63+
@Test
64+
void testRepository() {
65+
ExampleDocument exampleDocument = new ExampleDocument();
66+
exampleDocument.setText("Look, new @DataMongoTest!");
67+
exampleDocument = this.exampleRepository.save(exampleDocument);
68+
assertThat(exampleDocument.getId()).isNotNull();
69+
}
70+
71+
@TestConfiguration(proxyBeanMethods = false)
72+
static class TransactionManagerConfiguration {
73+
74+
@Bean
75+
MongoTransactionManager mongoTransactionManager(MongoDatabaseFactory dbFactory) {
76+
return new MongoTransactionManager(dbFactory);
77+
}
78+
79+
}
80+
81+
@TestConfiguration(proxyBeanMethods = false)
82+
static class MongoCustomizationConfiguration {
83+
84+
private static final String REPLICA_SET_NAME = "rs1";
85+
86+
@Bean
87+
IMongodConfig embeddedMongoConfiguration(EmbeddedMongoProperties embeddedProperties) throws IOException {
88+
IMongoCmdOptions cmdOptions = new MongoCmdOptionsBuilder().useNoJournal(false).build();
89+
return new MongodConfigBuilder().version(Version.Main.PRODUCTION)
90+
.replication(new Storage(null, REPLICA_SET_NAME, 0)).cmdOptions(cmdOptions)
91+
.stopTimeoutInMillis(60000).build();
92+
}
93+
94+
@Bean
95+
MongoInitializer mongoInitializer(MongoClient client, MongoTemplate template) {
96+
return new MongoInitializer(client, template);
97+
}
98+
99+
static class MongoInitializer implements InitializingBean {
100+
101+
private final MongoClient client;
102+
103+
private final MongoTemplate template;
104+
105+
MongoInitializer(MongoClient client, MongoTemplate template) {
106+
this.client = client;
107+
this.template = template;
108+
}
109+
110+
@Override
111+
public void afterPropertiesSet() throws Exception {
112+
List<ServerDescription> servers = this.client.getClusterDescription().getServerDescriptions();
113+
assertThat(servers).hasSize(1);
114+
ServerAddress address = servers.get(0).getAddress();
115+
BasicDBList members = new BasicDBList();
116+
members.add(new Document("_id", 0).append("host", address.getHost() + ":" + address.getPort()));
117+
Document config = new Document("_id", REPLICA_SET_NAME);
118+
config.put("members", members);
119+
MongoDatabase admin = this.client.getDatabase("admin");
120+
admin.runCommand(new Document("replSetInitiate", config));
121+
Awaitility.await().atMost(Duration.ofMinutes(1)).until(() -> {
122+
try (ClientSession session = this.client.startSession()) {
123+
return true;
124+
}
125+
catch (Exception ex) {
126+
return false;
127+
}
128+
});
129+
this.template.createCollection("exampleDocuments");
130+
}
131+
132+
}
133+
134+
}
135+
136+
}

0 commit comments

Comments
 (0)