java Junit4:预期=异常不适用于 SPRING

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1108066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:12:34  来源:igfitidea点击:

Junit4 : expected=Exception not working with SPRING

javaspringjunit

提问by ravinikam

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) 注释来测试预期的异常。我的代码如下:

@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.

在调试代码后,我发现代码按预期抛出异常,但它在 spring 框架类中的某个地方被吃掉了。

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 :

我用旧方法尝试了同样的方法(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.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.

而且我确信这是因为 RuntimeException 我抛出了保存但无法捕获它或通过预期子句的测试。

anybody have any idea whats going wrong?

有人知道出了什么问题吗?

采纳答案by Brendan Richards

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.

这是我在 Junit 4.5 中发现的一种解决方法 - 将 @Transactional 和 @ExpectedException 分成嵌套函数。我猜这个问题与 spring 围绕 @Transactional 方法的 aop 内容有关。

@Test
@ExpectedException(org.springframework.dao.DataIntegrityViolationException.class)
public void Test10UniqueName()
{
    DoTest10UniqueName();
}

@Transactional
public void DoTest10UniqueName()
{
    final String NAME = "NAME";
    ProductCategoryDAO dao = DAOFactory.getProductCategoryDAO();
    ProductCategory test1 = new ProductCategory();
    test1.setName(NAME);
    ProductCategory test2 = new ProductCategory();
    test2.setName(NAME);
    dao.save(test1);
    dao.save(test2);
}

回答by Bertolt

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.

原来我的第一个答案是错误的。@Test(expected=...) 和 @ExpectedException 都可以工作,但Spring TestContext 和 Junit 4.5之间存在一些不兼容。使用 Junit 4.4 为我解决了这个问题。最后。

回答by Paul McKenzie

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 isswallowed. I don't think anything is going wrong, you just need to make sure you understand what it is you are trying to test.

要么您正在运行单元测试,在这种情况下不应使用 Spring TX,要么您正在运行某种集成测试,您想测试当运行时异常吞下时 save 方法的作用。我认为没有任何问题,您只需要确保您了解要测试的内容。