Java @Spring测试中的事务注释

Java @Spring测试中的事务注释,java,spring-transactions,spring-test,Java,Spring Transactions,Spring Test,我正在阅读关于Spring测试的Spring文档,内容如下: 关于在测试中使用@Transactinoal,它说: 如果您的测试是@Transactional,那么默认情况下,它会在每个测试方法结束时回滚事务。然而,由于使用随机_端口或定义的_端口的这种安排隐式地提供了一个真正的servlet环境,HTTP客户机和服务器在单独的线程中运行,因此在单独的事务中运行。在这种情况下,在服务器上启动的任何事务都不会回滚 我不明白在这种情况下,服务器上启动的任何事务都不会回滚到底意味着什么。 非常感谢您的

我正在阅读关于Spring测试的Spring文档,内容如下:

关于在测试中使用@Transactinoal,它说:

如果您的测试是@Transactional,那么默认情况下,它会在每个测试方法结束时回滚事务。然而,由于使用随机_端口或定义的_端口的这种安排隐式地提供了一个真正的servlet环境,HTTP客户机和服务器在单独的线程中运行,因此在单独的事务中运行。在这种情况下,在服务器上启动的任何事务都不会回滚

我不明白在这种情况下,服务器上启动的任何事务都不会回滚到底意味着什么。


非常感谢您的帮助。

这意味着您的服务器不会回滚您的更改,因为它将在测试环境以外的其他环境中运行。 只有您在测试环境中所做的更改才会回滚

例如:

@Autowired
私有任意存储库任意存储库;
@试验
@交易的
void testSave(){
anyRepository.save(新建AnyEntity());
//将从测试环境中创建一个实体
}
@试验
@交易的
void testRead(){
anyRepository.findAll();
//无法找到任何实体,因为它们已回滚
}
相反,如果您使用
@springbootest(webEnvironment=webEnvironment.DEFINED_PORT)
启动了一个Spring的本地实例,它将从您的单元测试环境中分离,因此:

@Autowired
MockMvc-mvc;
@试验
@交易的
void testSave(){
执行(post(/*足以创建实体*/);
//您的服务器与测试环境分离,将实体持久化
}
@试验
@交易的
void testRead(){
perform(获取(/*足够获取该实体*/);
//将获取以前创建的实体(如果以前运行过testSave)
}
如果要在发送web请求后回滚,可以使用注释重置上下文或检查

编辑:根据原始帖子的评论,不清楚您是否需要使用
WebEnvironment.RANDOM\u PORT
,或者这是一个简单的问题。
最可能的情况是,如果您不需要
WebEnvironment.RANDOM\u PORT
,您可以简单地使用
WebEnvironment.MOCK
,它在JUnit测试的相同环境中运行,因此实际上会回滚


事务仅在本地工作。如果您正在运行集成测试,您实际上发出的是HTTP请求,则HTTP请求不是事务性的。@M.Denium。谢谢。那么,如果使用集成测试使用HttpRequest,您可以做些什么来回滚事务?您不能简单地使用
WebEnvironment.DEFINED\u PORT
Web环境。随机\u端口
,或使用。@Vincent C。感谢您的回复。如果您用此注释更新您的答案,我将不胜感激。使用
脏上下文
会导致再次加载应用程序上下文以进行下一次测试,这非常耗时。在这种情况下,使用
WebEnvironment.NONE/MOCK
似乎是更好的选择您提到过。使用NONE或MOCK是否会遗漏任何内容。我知道应用程序不会在容器中运行,但它真的会造成伤害吗?我以为您需要使用这两个选项中的一个。如果不需要,您很可能只需要
WebEnvironment.MOCK
(这是默认设置,因此您只需使用
@SpringBootTest
,而无需任何参数)。谢谢Vincent。这确实帮助了我。由于我正在测试集成,据称最好不要使用MOCK,因为它不会在容器中运行应用程序,因此不会进行完整的端到端测试。但我不明白如果使用MOCK而不是(例如)我会错过什么RANDOM_PORT。换句话说,在使用RANDOM_PORT时可以捕获哪些类型的错误,而在使用MOCK时不可能捕获这些错误。这对您有帮助吗?不,它仍然无法回答哪些场景只包含在
RANDOM_PORT
中,而不包含在
MOCK
中。无论如何,我可能会在另一个问题中问它。