Spring unittest - 异常

时间:2016-02-03 16:20:43

标签: java spring transactions persistence rollback

我有这个单元测试,我想以这种方式使用它:

  • 如果没有例外,则提交给DB。

  • 如果有异常,则回滚所有内容。

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "/config/myContext.xml" })
    public class transactionTest {
    
    ...
    
    @Test
    @Transactional(propagation = Propagation.REQUIRED, timeout = 60000,rollbackFor={Exception.class})
    @Rollback(false)
    public void testPersitMySubmissionOnlyIfNoExceptionsArePresent() throws Exception {  
        Submission submission = createSubmission();
        submissionService.persistSubmission(submission); //persist to DB
        Long submissionId = submission.getId();
    
    
        System.out.println("");
        System.out.println("#" + submissionId + " submission created.");
        System.out.println("");
    
        throw new Exception("I'm a problem!!!!!!!!!!!!!!"); //it simulates a problem, then I expect a rollback.
    
    }
    
    private Submission createSubmission(){
        //create an instance of Submission
    }
    
    }
    

为什么在上述情况下交易没有回滚? 我怎么写它才能做到这一点?

2 个答案:

答案 0 :(得分:0)

试试这个......

@ContextConfiguration(locations = { "/config/myContext.xml" })
public class TransactionTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Test
    //@Rollback(false) 
    public void testPersitMySubmissionOnlyIfNoExceptionsArePresent() throws Exception {
        Submission submission = createSubmission();
        submissionService.persistSubmission(submission); // persist to DB
        Long submissionId = submission.getId();

        System.out.println("");
        System.out.println("#" + submissionId + " submission created.");
        System.out.println("");

        throw new Exception("I'm a problem!!!!!!!!!!!!!!"); // it simulates a
                                                            // problem, then I
                                                            // expect a
                                                            // rollback.
        //  Commit the transcation programatically
        //  Will cause compile error as unreachable code after thrown exception
        TestTransaction.flagForCommit();
        TestTransaction.end();
    }

    private Submission createSubmission() {
        // create an instance of Submission
    }
}

编辑:我的理解是这样可行。我个人从未想过这种行为。测试应处于已知状态,并且根据定义,提交测试数据会违反该测试数据。我现在无法测试,但您应该能够使用 TestTransaction 静态方法来实现相同的结果。样本已更新。

答案 1 :(得分:0)

我用这种方法解决了:

import org.springframework.transaction.PlatformTransactionManager;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/config/myContext.xml" })
public class transactionTest {

@Inject
PlatformTransactionManager transactionManager;

@Test
@Transactional(propagation = Propagation.REQUIRED, timeout = 60000,rollbackFor={Exception.class})
@Rollback(false)
public void testPersitMySubmissionOnlyIfNoExceptionsArePresent() throws Exception {  
    //instantiate the transaction manager programmatically
    DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
    TransactionStatus transaction = transactionManager.getTransaction(definition);

    try {
    // persist data to DB
    Submission submission = createSubmission();
    submissionService.persistSubmission(submission); //persist to DB
    Long submissionId = submission.getId();


    System.out.println("");
    System.out.println("#" + submissionId + " submission created.");
    System.out.println("");

    //simulate the problem
    raiseException()

    } catch(Exception e){

        //rollback the transaction
        transactionManager.rollback(transaction);
        return;
    }

    // if I'm here, I haven't got any exception, then I can commit
    transactionManager.commit(transaction);

}

private Submission createSubmission(){
    //create an instance of Submission
}


private void raiseException() throws Exception{
        throw new Exception("I'm a problem!!!!!!!!!!!!!!");
}

}