Please give me tips to get my failing JUnit test to pass in my Spring Boot app.
I have a Service that needs to delete rows from tables A and B (from a H2 database) in a transactional manner such that: if A is modified and then an exception occurs before B is modified, then neither A nor B are modified. However, even after
@Transactional
to the PUBLIC Service::deleteRows
method, and@EnableTransactionManagement
to the @Configuration
class that produces the JdbcTemplate
that all repositories use, andthe transaction still doesn't rollback.
Here's the failing JUnit testcase
// Service.java
@Transactional
public void deleteRows() {
aRepository.deleteRow(123);
bRepository.deleteRow(123);
}
// ServiceTest.java
@Test
void test() {
// first ensure that an exception is thrown when bRepository.deleteRow() is called
// FYI deleteRow() calls jdbcTemplate.update()
doThrow(RuntimeException.class)
.when(mockJdbcTemplate)
.update(any(), eq(123));
BRepository mockBRepository = new BRepository(mockJdbcTemplate);
Service service = new Service(realARepository, mockBRepository);
assertTableHasRows(1, "TABLE_A"); // before calling the service, TABLE_A has 1 row
assertThrows(RuntimeException.class, service::deleteRows);
assertTableHasRows(1, "TABLE_A"); // TABLE_A should still have 1 row when an exception occurs during the tx
}
删除 @Transactional 并再次运行测试。
In the end the problem was solved by NOT using mocking to trigger an exception. Instead, we set up the database schema so that normal operation of service::deleteRows would trigger an exception.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.