Spring存储库:即使缺少@Transactional,Junit测试也能成功进行自定义删除



我有一个Spring存储库,它有一个这样的方法:

Long deleteByStatusAndTriggeredBefore(String status, Timestamp triggered);

在Junit测试中测试此方法时,它确实按预期工作。

@DataJpaTest
public class AlertRepositoryTest {
@Autowired
@Qualifier("alertRepository")
private AlertRepository underTest;
@AfterEach
void tearDown(){
underTest.deleteAll();
}
@Test
void testUpdateAndDelete() {
Timestamp triggered = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
Timestamp fixed = java.sql.Timestamp.valueOf("2012-09-23 10:10:10.0");
Alert alert1 = new Alert("FIXED", "event1", 0L, 0L, triggered, fixed, "domain1", "service1", "metric1", "context1", 1L, 1L);
Alert alert2 = new Alert("FIXED", "event2", 0L, 0L, triggered, fixed, "domain2", "service2", "metric2", "context2", 1L, 1L);
underTest.save(alert1);
underTest.save(alert2);

// some other assertions ...
// As expected, the elements get deleted and the database is empty
Timestamp deletion = java.sql.Timestamp.valueOf("2019-09-23 10:10:10.0");
underTest.deleteByStatusAndTriggeredBefore("FIXED", deletion);
Page<Alert> alertReturned = underTest.findByStatus("FIXED", Pageable.unpaged());
assertThat(alertReturned.getContent().size()).isEqualTo(0);  
}
}

但是,删除操作对我们的生产数据库不起作用。为了让它在生产数据库上工作,我们必须将@Transactional注释添加到存储库中的方法中

@Transactional
Long deleteByStatusAndTriggeredBefore(String status, Timestamp triggered);

这是一个问题,因为测试是有效的,但在生产中不起作用。当缺少事务性注释时,是否有可能使此测试失败?测试被配置为在内存中的H2数据库上运行。

它在测试中工作的原因是@DataJpaTest注释包含@Transactional元注释。因此,整个测试方法都包含了一个事务,这使得AlertRepository方法可以在没有错误的情况下运行。

如果你想让它在测试中失败,你可以覆盖@Transactional注释,如下所示:

DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyNonTransactionalTests {
// ...
}

有关此行为的详细信息,请参阅文档。

最新更新