Spring @Transactional 和回滚不起作用,spring 集成测试
Spring @Transactional and rollback not working, spring integration tests
我正在 spring 中进行集成测试,在这个例子中我测试了一个服务层。
我有一个问题,在服务的添加测试期间,回滚不起作用,并且总是向基础添加项目,但不删除它。
我在测试上添加了@Transactional 和@TestPropertySource 注解class,
还有 application-test.properties 测试成功但是没有执行回滚,总是在测试数据库中添加一个新项目。
我的测试class和添加地址的测试方法(最后一个):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TicketServiceApplication.class)
@Transactional
@TestPropertySource("classpath:application-test.properties")
public class AddressServiceIntegrationTest {
@Autowired
private AddressService addressService;
@Autowired
private AddressRepository addressRepository;
@Test
public void findAllSuccessTest(){
List<Address> result = addressService.finfAllAddress();
assertNotNull(result);
assertFalse(result.isEmpty());
assertEquals(2, result.size());
}
@Test
public void findOneAddressExistTest_thenReturnAddress(){
Long id = AddressConst.VALID_ID_ADDRESS;
Address a = addressService.findOneAddress(id);
assertEquals(id, a.getId());
}
@Test(expected = EntityNotFoundException.class)
public void findOneAddressNotExistTest_thenThrowException(){
Long id = AddressConst.NOT_VALID_ID_ADDRESS;
Address a = addressService.findOneAddress(id);
}
@Test
public void addAddressSuccessTest(){
int sizeBeforeAdd = addressRepository.findAll().size();
Address address = AddressConst.newAddressToAdd();
Address result = addressService.addAddress(address);
int sizeAfterAdd = addressRepository.findAll().size();
assertNotNull(result);
assertEquals(sizeBeforeAdd+1, sizeAfterAdd);
assertEquals(address.getCity(), result.getCity());
assertEquals(address.getState(), result.getState());
assertEquals(address.getNumber(), result.getNumber());
assertEquals(address.getLatitude(), result.getLatitude());
assertEquals(address.getLongitude(), result.getLongitude());
assertEquals(address.getStreet(), result.getStreet());
}
}
我的申请-test.properties :
spring.datasource.url= jdbc:mysql://localhost:3306/kts_test&useSSL=false&
useUnicode=true&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
并且当执行添加地址测试时,每次在我的 kts_test 数据库(用于测试的数据库)中添加新项目而不是回滚。
这是控制台的日志,可以看到调用了回滚但是没有执行,因为我测试完刷新数据库的时候留下了新的item,并没有删除。
INFO 10216 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@3e58a80e testClass = AddressServiceIntegrationTest, testInstance = com.ftn.services.address.AddressServiceIntegrationTest@4678ec43, testMethod = addAddressSuccessTest@AddressServiceIntegrationTest, testException = [null],...
最后写一下,我试过@Transactional上面的方法,我也试过@Rollback上面的方法或者@Rollback(true),试过改变application-test.properties,我已经不知道是什么错误了.
如果有人能提供帮助,我将不胜感激。谢谢。
Hibernate 默认使用 MyISAM 存储引擎创建表 - 此引擎不支持事务。您需要有 InnoDB 表:
- 要么使用 Flyway 之类的工具手动管理您的数据库迁移(恕我直言,首选选项,这样您就可以拥有完整的控制权),然后在测试中关闭重新创建数据库。
- 或在配置中设置正确的引擎:
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
或(已弃用)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
我正在 spring 中进行集成测试,在这个例子中我测试了一个服务层。
我有一个问题,在服务的添加测试期间,回滚不起作用,并且总是向基础添加项目,但不删除它。
我在测试上添加了@Transactional 和@TestPropertySource 注解class, 还有 application-test.properties 测试成功但是没有执行回滚,总是在测试数据库中添加一个新项目。
我的测试class和添加地址的测试方法(最后一个):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TicketServiceApplication.class)
@Transactional
@TestPropertySource("classpath:application-test.properties")
public class AddressServiceIntegrationTest {
@Autowired
private AddressService addressService;
@Autowired
private AddressRepository addressRepository;
@Test
public void findAllSuccessTest(){
List<Address> result = addressService.finfAllAddress();
assertNotNull(result);
assertFalse(result.isEmpty());
assertEquals(2, result.size());
}
@Test
public void findOneAddressExistTest_thenReturnAddress(){
Long id = AddressConst.VALID_ID_ADDRESS;
Address a = addressService.findOneAddress(id);
assertEquals(id, a.getId());
}
@Test(expected = EntityNotFoundException.class)
public void findOneAddressNotExistTest_thenThrowException(){
Long id = AddressConst.NOT_VALID_ID_ADDRESS;
Address a = addressService.findOneAddress(id);
}
@Test
public void addAddressSuccessTest(){
int sizeBeforeAdd = addressRepository.findAll().size();
Address address = AddressConst.newAddressToAdd();
Address result = addressService.addAddress(address);
int sizeAfterAdd = addressRepository.findAll().size();
assertNotNull(result);
assertEquals(sizeBeforeAdd+1, sizeAfterAdd);
assertEquals(address.getCity(), result.getCity());
assertEquals(address.getState(), result.getState());
assertEquals(address.getNumber(), result.getNumber());
assertEquals(address.getLatitude(), result.getLatitude());
assertEquals(address.getLongitude(), result.getLongitude());
assertEquals(address.getStreet(), result.getStreet());
}
}
我的申请-test.properties :
spring.datasource.url= jdbc:mysql://localhost:3306/kts_test&useSSL=false&
useUnicode=true&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
并且当执行添加地址测试时,每次在我的 kts_test 数据库(用于测试的数据库)中添加新项目而不是回滚。
这是控制台的日志,可以看到调用了回滚但是没有执行,因为我测试完刷新数据库的时候留下了新的item,并没有删除。
INFO 10216 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@3e58a80e testClass = AddressServiceIntegrationTest, testInstance = com.ftn.services.address.AddressServiceIntegrationTest@4678ec43, testMethod = addAddressSuccessTest@AddressServiceIntegrationTest, testException = [null],...
最后写一下,我试过@Transactional上面的方法,我也试过@Rollback上面的方法或者@Rollback(true),试过改变application-test.properties,我已经不知道是什么错误了.
如果有人能提供帮助,我将不胜感激。谢谢。
Hibernate 默认使用 MyISAM 存储引擎创建表 - 此引擎不支持事务。您需要有 InnoDB 表:
- 要么使用 Flyway 之类的工具手动管理您的数据库迁移(恕我直言,首选选项,这样您就可以拥有完整的控制权),然后在测试中关闭重新创建数据库。
- 或在配置中设置正确的引擎:
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
或(已弃用)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect