как я могу протестировать метод с аннотацией @Transaction. Я написал метод, который работает, если я тестирую его при запуске приложения (вручную). Но мой тест на это не работает. Моя цель - написать тест, который убедится, что мой метод транзакции работает при возникновении исключения, поэтому в БД ничего не сохраняется. Возможно, этого достаточно, чтобы проверить, существует ли аннотация Transaction, в уверенности, что spring работает нормально. : / Но для меня это некрасиво.
Так что моя цель не в том, чтобы проверить функциональность транзакции пружин. Моя цель - провести тест, чтобы убедиться, что ничего не будет сохранено в базе данных, если произойдет исключение. Может, есть способ лучше это проверить.
Я каждый раз сбрасываю базу данных перед запуском теста. Идентификатор компании - это каждый раз случайное длинное число.
Настройка
- java: 11
- springboot: 2.3.1
- mongodb: 4.2.7
application.yml
spring:
data:
mongodb:
uri: mongodb://okAdmin:test@mongo_one:27017,mongo_two:27018,mongo_three:27019/?replicaSet=rs0
database: "ok"
auto-index-creation: false
Mon go конфигурация для пружины
@Configuration
public class MongoTransactionConfig extends AbstractMongoClientConfiguration {
@Value("${spring.data.mongodb.database}")
private String database;
@Value("${spring.data.mongodb.uri}")
private String mongo_uri;
@Bean
MongoTransactionManager transactionManager(MongoDatabaseFactory mongoDatabaseFactory) {
return new MongoTransactionManager(mongoDatabaseFactory);
}
@Bean
public MongoClient mongoClient() {
return MongoClients.create(mongo_uri);
}
@Override
protected String getDatabaseName() {
return database;
}
}
Метод
@Slf4j
@Service
public class CompanyService {
public static final int MIN_NUMBER_OF_BRANCHES = 1;
private final CompanyRepository companyRepository;
@Autowired
public CompanyService(@NonNull CompanyRepository companyRepository) {
this.companyRepository = companyRepository;
}
// TODO : TEST
@Transactional // (rollbackFor = {StoreException.class}) => NOT WORKING FOR TESTS/NO CATCHING
public void addBranch(@NonNull Branch branch){
log.debug("Service: Add branch to company");
long companyId = branch.getCompanyId();
companyRepository.addBranch(branch);
long branches_number = companyRepository.countBranchesForCompany(companyId);
if (branches_number == MIN_NUMBER_OF_BRANCHES) {
companyRepository.setSignupCompleted(companyId, true);
}
}
}
Тест
@SpringBootTest(properties = {
"spring.data.mongodb.database=ok_test"
})
//@Transactional
class CompanyServiceMongoTest {
private final String COLLECTION_BRANCHES = "branches";
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private CompanyService testObject;
@Autowired
private CompanyRepository companyRepository;
@Test
void addBranch_test_transaction_company_not_saved(){
// PREPARE
Branch branchTestDummy = BranchTest.createBranchTestDummy();
Query branchQuery = new Query();
branchQuery.addCriteria(Criteria.where("company_id").is(branchTestDummy.getCompanyId()));
// ACTION
assertThrows(StoreException.class, ()-> testObject.addBranch(branchTestDummy));
// CHECK
boolean exists = mongoTemplate.exists(branchQuery, BranchDao.class, COLLECTION_BRANCHES);
assertFalse(exists);
}
}
Результат теста
org.opentest4j.AssertionFailedError:
Expected :false
Actual :true
at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:40)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:35)
at org.junit.jupiter.api.Assertions.assertFalse(Assertions.java:210)
at com.localkoop.server.components.company.core.services.CompanyServiceMongoTest.addBranch_test_transaction_company_not_saved(CompanyServiceMongoTest.java:102)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Запуск вывода на консоль
2020-06-17 11:12:34.635 INFO 182967 --- [mongo_two:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1426609, serverValue:1511263}] to mongo_two:27017
2020-06-17 11:12:34.635 DEBUG 182967 --- [mongo_two:27017] org.mongodb.driver.cluster : Checking status of mongo_two:27017
2020-06-17 11:12:34.635 DEBUG 182967 --- [mongo_two:27017] org.mongodb.driver.protocol.command : Sending command '{"ismaster": 1, "$db": "admin", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1592385154, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "2Qn1NUq/OPeFI3jd2aPIoloM/x0=", "subType": "00"}}, "keyId": 6837089852169650179}}}' with request id 2853624 to database admin on connection [connectionId{localValue:1426609, serverValue:1511263}] to server mongo_two:27017
2020-06-17 11:12:34.635 DEBUG 182967 --- [mongo_two:27017] org.mongodb.driver.protocol.command : Execution of command with request id 2853624 completed successfully in 0.32 ms on connection [connectionId{localValue:1426609, serverValue:1511263}] to server mongo_two:27017
2020-06-17 11:12:34.636 INFO 182967 --- [mongo_two:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=mongo_two:27017, type=REPLICA_SET_PRIMARY, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=8, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=403948, setName='rs0', canonicalAddress=mongo_one:27017, hosts=[mongo_one:27017], passives=[mongo_two:27017, mongo_three:27017], arbiters=[], primary='mongo_one:27017', tagSet=TagSet{[]}, electionId=7fffffff0000000000000009, setVersion=1, lastWriteDate=Wed Jun 17 11:12:34 CEST 2020, lastUpdateTimeNanos=9570708142930}
2020-06-17 11:12:34.636 INFO 182967 --- [mongo_two:27017] org.mongodb.driver.cluster : Adding discovered server mongo_three:27017 to client view of cluster
2020-06-17 11:12:34.636 INFO 182967 --- [mongo_two:27017] org.mongodb.driver.cluster : Canonical address mongo_one:27017 does not match server address. Removing mongo_two:27017 from client view of cluster
2020-06-17 11:12:34.636 DEBUG 182967 --- [mongo_two:27017] org.mongodb.driver.cluster : Updating cluster description to {type=REPLICA_SET, servers=[{address=mongo_one:27017, type=REPLICA_SET_PRIMARY, roundTripTime=0.6 ms, state=CONNECTED}, {address=mongo_three:27017, type=UNKNOWN, state=CONNECTING}]
2020-06-17 11:12:34.636 DEBUG 182967 --- [mongo_two:27017] org.mongodb.driver.connection : Closing connection connectionId{localValue:1426609, serverValue:1511263}
2020-06-17 11:12:34.637 INFO 182967 --- [ngo_three:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1426610, serverValue:1511264}] to mongo_three:27017
2020-06-17 11:12:34.637 DEBUG 182967 --- [ngo_three:27017] org.mongodb.driver.cluster : Checking status of mongo_three:27017
2020-06-17 11:12:34.637 DEBUG 182967 --- [ngo_three:27017] org.mongodb.driver.protocol.command : Sending command '{"ismaster": 1, "$db": "admin", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1592385154, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "2Qn1NUq/OPeFI3jd2aPIoloM/x0=", "subType": "00"}}, "keyId": 6837089852169650179}}}' with request id 2853626 to database admin on connection [connectionId{localValue:1426610, serverValue:1511264}] to server mongo_three:27017
2020-06-17 11:12:34.637 DEBUG 182967 --- [ngo_three:27017] org.mongodb.driver.protocol.command : Execution of command with request id 2853626 completed successfully in 0.36 ms on connection [connectionId{localValue:1426610, serverValue:1511264}] to server mongo_three:27017
2020-06-17 11:12:34.637 INFO 182967 --- [ngo_three:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=mongo_three:27017, type=REPLICA_SET_PRIMARY, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=8, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=457039, setName='rs0', canonicalAddress=mongo_one:27017, hosts=[mongo_one:27017], passives=[mongo_two:27017, mongo_three:27017], arbiters=[], primary='mongo_one:27017', tagSet=TagSet{[]}, electionId=7fffffff0000000000000009, setVersion=1, lastWriteDate=Wed Jun 17 11:12:34 CEST 2020, lastUpdateTimeNanos=9570709659086}
2020-06-17 11:12:34.637 INFO 182967 --- [ngo_three:27017] org.mongodb.driver.cluster : Adding discovered server mongo_two:27017 to client view of cluster
2020-06-17 11:12:34.637 INFO 182967 --- [ngo_three:27017] org.mongodb.driver.cluster : Canonical address mongo_one:27017 does not match server address. Removing mongo_three:27017 from client view of cluster
2020-06-17 11:12:34.637 DEBUG 182967 --- [ngo_three:27017] org.mongodb.driver.cluster : Updating cluster description to {type=REPLICA_SET, servers=[{address=mongo_one:27017, type=REPLICA_SET_PRIMARY, roundTripTime=0.6 ms, state=CONNECTED}, {address=mongo_two:27017, type=UNKNOWN, state=CONNECTING}]
2020-06-17 11:12:34.637 DEBUG 182967 --- [ngo_three:27017] org.mongodb.driver.connection : Closing connection connectionId{localValue:1426610, serverValue:1511264}
СПАСИБО ЗА ПОМОЩЬ