Junit4:预期=异常不适用于SPRING
我正在尝试使用 @Test(expected = RuntimeException.class) 注释 为了测试预期的异常。 我的代码如下:
@Test(expected = RuntimeException.class)
public void testSaveThrowsRuntimeException(){
User user = domain.save(null);
}
我的保存方法简单如下:
public User save(User newUser) {
if(newUser == null) {
throw new RuntimeException();
}
//saving code goes here
}
调试代码后,我发现代码按预期抛出异常,但它在 Spring 框架类中的某个位置被吃掉。
我尝试了与旧方法相同的方法(try catch 块),但仍然无法在测试中捕获该异常,并且测试不断在 Junit 的 runafter 方法中抛出错误:
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1031)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:504)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:344)
at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:307)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:338)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:142)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: javax.transaction.RollbackException
at org.objectweb.jotm.TransactionImpl.commit(TransactionImpl.java:245)
at org.objectweb.jotm.Current.commit(Current.java:488)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028)
... 23 more
我确信这是因为我在 save 中抛出了 RuntimeException但无法捕获它或通过预期子句的测试。
有人知道出了什么问题吗?
I'm trying to use the @Test(expected = RuntimeException.class) annotation in
order to test for an expected exception. My code is as follows:
@Test(expected = RuntimeException.class)
public void testSaveThrowsRuntimeException(){
User user = domain.save(null);
}
and my save method simple like this :
public User save(User newUser) {
if(newUser == null) {
throw new RuntimeException();
}
//saving code goes here
}
after debugging the code I found that code throwing the exception as expected but its getting eaten somewhere in between in spring framework classes.
I tried the same with old way (try catch block) but still I am not able to catch that exception in test and test keeps throwing errors in runafter method of Junit :
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1031)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:504)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:344)
at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:307)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:338)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:142)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: javax.transaction.RollbackException
at org.objectweb.jotm.TransactionImpl.commit(TransactionImpl.java:245)
at org.objectweb.jotm.Current.commit(Current.java:488)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028)
... 23 more
And I am sure this is because of that RuntimeException I am throwing in save but not able catch it or pass the test with expected clause.
anybody have any idea whats going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
事实证明我的第一个答案是错误的。 @Test(expected=...) 和 @ExpectedException 都可以工作,但是 Spring 之间存在一些不兼容性TestContext 和 Junit 4.5。 使用 Junit 4.4 解决了我的问题。 最后。
Turned out that my first answer was wrong. Both @Test(expected=...) and @ExpectedException work, but there is some incompability between the Spring TestContext and Junit 4.5. Using Junit 4.4 solved the problem for me. Finally.
这是我在 Junit 4.5 中发现的一个解决方法 - 将 @Transactional 和 @ExpectedException 分离到嵌套函数中。
我想这个问题与 spring 在 @Transactional 方法周围放置的 aop 内容有关。
Here's a work-around I found to with Junit 4.5 - separate the @Transactional and @ExpectedException into nested functions.
I guess the problem is something to do with the aop stuff spring puts around a @Transactional method.
要么您正在运行单元测试,在这种情况下 Spring TX 不应该参与其中,要么您正在运行某种集成测试,您想要测试当运行时异常发生时 save 方法的作用 吞下去了。 我不认为有什么问题,你只需要确保你明白你要测试的是什么。
Either you're running a unit test, in which case Spring TX shouldn't come in to play, or you're running some kind of integration test where you want to test what the save method does when your runtime exception is swallowed. I don't think anything is going wrong, you just need to make sure you understand what it is you are trying to test.