2017-09-04 64 views
0

測試方法remove正在嘗試刪除某些用戶,其ID爲147但該ID不存在。如果我啓用Rollback(false),我得到一個異常(預期的行爲),但沒有它,測試通過沒有問題。所以我有兩個問題:使用回滾時不會拋出異常的交易測試方法

  1. 爲什麼只有在禁用回滾時測試失敗?
  2. 是否可以通過 獲取異常啓用回滾?

UserDao是從具有@Transactional(默認選項)的通用DAO類和@Repository繼承(與bean的名字)在類級別的註解。

Here是禁用回滾時出現的異常。

我使用Spring框架4.3.9,休眠5.2.10和JUnit 4.12

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@Transactional 
@ContextConfiguration({ 
     "classpath:myapp-config-test.xml", 
     "classpath:hib-test.xml"}) 
public class UserControllerTest { 

    private MockMvc mockMvc; 
    private MvcResult mvcResult; 
    private final String basePath = "https://stackoverflow.com/users/"; 

    @Autowired 
    private UserDao userDao; 

    @Before 
    public void setUp() throws Exception { 
     mockMvc = MockMvcBuilders.standaloneSetup(new UserController(userDao)).build(); 
    } 

    @Test 
    //@Rollback(false) 
    public void remove() throws Exception { 
     mockMvc.perform(delete(basePath + "147")).andExpect(status().isOk()); 
    } 
} 

回答

2

閱讀堆棧跟蹤,從下到上:

Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:67) 
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:54) 
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3315) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3552) 
    at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:99) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:589) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1435) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491) 
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201) 
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2411) 
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220) 
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68) 
    at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:582) 
    ... 24 more 

你可以看到異常發生在交易管理器提交交易時:

at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:582) 

提交交易原因Hibernate的Session刷新已作出,並保存在內存中的變化:

at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201) 

事實上,沖洗導致實際上可以在數據庫上執行刪除:

at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:99) 

而且,由於刪除不刪除任何東西,拋出異常:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 

因此,爲了實際執行刪除操作,並拋出預期的異常,則需要刷新。

但是,您不應該在MVC控制器的單元測試中測試DAO的行爲(甚至更少,Hibernate的行爲,它已經由Hibernate自己測試過)。相反,當單元測試控制器時,您應該嘲笑控制器(即DAO)的依賴關係。並且對DAO進行另一項測試。

+0

我很擔心這個簡單的事實:爲什麼當(理論上)測試失敗時測試通過?謝謝你的解釋 – Chu