我正在测试的服务方法是这样的
void updateOrderStatusToComplete(def orderIdList) {
if (orderIdList) {
try{
def response = Order.executeUpdate("update Order tabrr set tabrr.status = :status where tabrr.id in (:idList)", [status: "Completed", idList: orderIdList])
} catch(Exception e){
throw new RuntimeException("Error updating orders to Complete")
}
}
}
我的测试首先创建4个订单。
void "updateRowsToMatch" (){
given: "we have 4 existing orders with status open"
def order1 = new Order(description: "item 1", price: 50.00, status: "Open")
order1.save()
def order2 = new Order(description: "item 2", price: 60.00, status: "Open")
order2.save
def order3 = new Order(description: "item 3", price: 70.00, status: "Open")
order3.save()
def order4 = new Order(description: "item 4", price: 80.00, status: "Open")
order4.save()
def orderIdList = [order1.id, order2.id, order3.id, order4.id]
when: "we use orderservice to update the rows status...."
orderservice.updateOrderStatusToComplete(orderIdList)
then: "the orders status should be updated to "Completed"
assert Order.get(order1.id).status == "Completed"
assert Order.get(order2.id).status == "Completed"
assert Order.get(order3.id).status == "Completed"
assert Order.get(order4.id).status == "Completed"
}
当我在测试前用表行在数据库中播种,并使用这些ID,然后测试通过,现有的表行就会被更新。这个问题似乎只发生在我在测试中创建表行的时候。但是有趣的是executeUpdate的返回值是4,这意味着事实上有4个表行被更新了,所以我在这里有点疑惑,为什么状态实际上没有改变.测试使用了@Integration和@Rollbackannotations,所以这意味着测试事务在测试期间被回滚而不是完全提交。但是我仍然可以使用Order.findById(...)或Order.findByDescription()检索已经保存的订单,所以我不知道为什么在测试期间会持续存在,而不是执行Update事务。
找到了解决方案。刷新似乎并不奏效,但清除会话却可以,所以在测试类的开头插入一个Hibernate SessionFactory的setter。
def sessionFactory
然后在保存对象
sessionFactory.currentSession.clear()
这样做可以更新和检索在测试中创建的对象。