1

我有一個Spring 3.1 MVC + Hibernate 3.6項目,它的junit4測試套裝。我的問題是在我的測試用例中沒有事務開始,甚至認爲我添加了一個@Transactional爲什麼交易不會在我的junit測試用例中啓動?

我的測試用例調用一個控制器和一個dao。在控制器中,無論如何都會啓動交易,所以它不會發生抱怨。在dao中,我添加了一個@Transactional(propagation = Propagation.MANDATORY)以確保它將接受測試的交易。目前它引發了一個IllegalTransactionStateException,我猜這意味着沒有當前的事務。

我試圖創建一個事務的programmaticaly,它確實工作,這意味着獲得道服務的AOP代理不是問題的原因。不過,我想用@Transactional註釋創建交易。

這裏是我道:

// ...imports... 

@Repository("taskDao") 
@Transactional(propagation = Propagation.MANDATORY) 
public class TaskHome implements TaskDao { 

    private static final Log log = LogFactory.getLog(TaskHome.class); 

    private SessionFactory sessionFactory; 

    @Autowired 
    public TaskHome(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public Task findById(int id) { 
     log.debug("getting Task instance with id: " + id); 
     try { 
      Task instance = (Task) this.sessionFactory.getCurrentSession().get(
        Task.class, id); // exception raised here! 
      if (instance == null) { 
       log.debug("get successful, no instance found"); 
      } else { 
       log.debug("get successful, instance found"); 
      } 
      return instance; 
     } catch (RuntimeException re) { 
      log.error("get failed", re); 
      throw re; 
     } 
    } 
    ... 
} 

這裏是我的測試案例:

// ...imports... 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({ "/test-config.xml", "/applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback = true) 
@Transactional 
public class TestTaskController { 

    private static ClassPathXmlApplicationContext context; 
    private static TaskDao taskDao; 

    @BeforeClass 
    public static void initHibernate() throws Exception { 
     context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
     taskDao = context.getBean("taskDao", TaskDao.class); 
    } 

    @Test 
    public void testOnSubmit() { 

     // expects an existing default transaction here 

     Task task = taskDao.findById(1); // fails already here 

     // ... calls the controller and does some tests. 

    } 

} 

我找遍了所有Spring的文檔中,並以任何方式我可以想像GOOGLE了它,但我不明白爲什麼交易沒有開始。 任何幫助非常歡迎。

+0

會發生什麼,當你刪除**(傳播= Propagation.MANDATORY)?** – ManuPK 2012-07-15 13:30:20

+0

它創建了一個新的交易,whi ch將阻止回滾。 – edwin 2012-07-15 19:52:50

回答

13

當使用@RunWith(SpringJUnit4ClassRunner.class),你應該獲得由SpringJUnit4ClassRunner創建的應用程序上下文豆,而不是從自己的一個。

在你的情況下出問題了,因爲@Transactional單元測試在由SpringJUnit4ClassRunner管理的應用程序上下文中創建一個事務,但是你調用從手動創建的應用程序上下文獲得的bean的方法。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({ "/test-config.xml", "/applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback = true) 
@Transactional 
public class TestTaskController { 
    @Autowired 
    private TaskDao taskDao; 

    ... 
} 

參見:

所以,通過自動裝配刪除您@BeforeClass方法,並獲得TaskDao

+0

確實有效。萬分感謝。我認爲我已經獲得了已經在記憶中創建的背景,但是在再次閱讀後,我看到了我的錯誤。 – edwin 2012-07-15 19:32:57

相關問題