测试方法remove
正在尝试删除标识为147
的某些用户,但此ID不存在。如果我启用Rollback(false)
我会得到一个异常(预期的行为)但没有它,测试通过没有问题。所以我有两个问题:
UserDao
继承自通用DAO类,它在类级别具有@Transactional
(默认选项)和@Repository
(带有bean名称)注释。
Here是我在禁用回滚时获得的异常。
我正在使用Spring Framework 4.3.9,Hibernate 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 = "/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());
}
}
答案 0 :(得分: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会话刷新已经发生的更改并保存在内存中:
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201)
实际上,flush会导致删除实际上在数据库上执行:
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进行了另一次测试。