spring、事务和单元测试 - 如何在类级别设置事务

发布于 2024-10-21 20:12:22 字数 140 浏览 1 评论 0 原文

我正在使用 Spring junit runner 及其事务功能在每次测试之前和之后启动和回滚事务。

然而,我有一个带有一些繁重数据库初始化的测试类,我希望每个测试(方法)在事务范围内运行,即在测试开始时启动一个事务,并在类中的所有测试完成后回滚它。

I'm using Spring junit runner, and its transaction capabilities to start and rollback transactions before and after every test.

However I have a test class with some heavy DB initialization and I want each test (method) to run within the transaction scope, i.e. start a transaction at the beginning of the test and roll it back after all tests in the class completed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九厘米的零° 2024-10-28 20:12:22

您是否知道在单个事务中将类中的所有测试方法放在一个事务中会导致很多麻烦?基本上,您不能再依赖于干净的数据库,因为其他测试方法会一路修改它。而且由于未指定测试方法的顺序,因此您也不能依赖它(因此您永远不会知道数据库到底保存什么)。本质上,您放弃了所有测试事务支持,您唯一的保证是在运行整个测试用例后,数据库将保持干净(因此其他测试用例不会受到影响)。

你的抱怨结束了。我不认为 Spring 支持这种开箱即用的行为(部分是由于上面强调的原因)。但是,如果您仔细查看 TransactionalTestExecutionListener,它负责Spring驱动的测试中的事务支持。

@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
    //...
    startNewTransaction(testContext, txContext);
}

并且:

@Override
public void afterTestMethod(TestContext testContext) throws Exception {
    //...
    endTransaction(testContext, txContext);
    //...
}

现在仔细观察,还有未实现的 beforeTestClassafterTestClass...您将在 9.3.5 Spring 参考文档。提示:编写您自己的侦听器并使用它来代替 TransactionalTestExecutionListener

Are You aware that having all the test methods inside your class within a single transaction will cause a lot of trouble? Basically you can no longer depend on having a clean database as other test methods will modify it along the way. And because the order of test methods is not specified, you cannot depend on it as well (so you'll never know what exactly does the database hold). Essentially You are giving up all test transactional support, your only guarantee is that after running the whole test case, the database will remain clean (so other test cases won't be affected).

End of grumbling thou. I don't think Spring supports such a behavior out-of-the-box (partially due to the reasons highlighted above). However, if You look closely at TransactionalTestExecutionListener, it is responsible for transactional support in Spring-powered tests.

@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
    //...
    startNewTransaction(testContext, txContext);
}

and:

@Override
public void afterTestMethod(TestContext testContext) throws Exception {
    //...
    endTransaction(testContext, txContext);
    //...
}

Now look even closer, there are unimplemented beforeTestClass and afterTestClass... You will find detailed instructions how to wire this all up in chapter 9.3.5 of Spring reference documentation. Hint: write your own listener and use it instead of TransactionalTestExecutionListener.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文