如何用Spock模拟EntityManager和Query?

时间:2017-05-11 18:09:20

标签: unit-testing jpa spock

使用spock我需要模拟对EntityManager / Query的调用。我试图模拟的代码行是:

entityManager.createNativeQuery("nativeQuery").setParameter(1, param1).getResultList()

entityManager.createNativeQuery的模拟返回一个空Query个对象。然后导致失败,因为您无法在null对象上调用方法。因此,我无法模拟结果集列表的返回。

我已经尝试将语句分解为单独的和伴随的模拟,但这也没有用,因为我仍然以null查询结束。

我不知道我现在是否有隧道视觉,或者如果这不能被嘲笑 - 至少对Spock来说。

所有帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

你需要做的是建立一个模拟的层次结构,它们将从最后一个开始相互返回:

查询:

def query = Mock(Query) {
   setParameter(_, _) >> it //here as mock itself is returned
   getResultList() >> []    //empty list
}

的EntityManager:

def manager = Mock(EntityManager) {
   createNativeQuery(_) >> query
}

等等。虽然你需要实现的是可行的,但它或多或少表明设计不好:每次模拟返回模拟时,仙女死亡,所以你应该避免这样的结构。你可以做的是将查询构建与它的执行分开 - 然后模拟将更容易。样本规范:

def 'fairy has just died'() {
   given:
   def query = Mock(Query) {
      setParameter(_, _) >> it //here as mock itself is returned
      getResultList() >> [1]    //empty list
   }

   def manager = Mock(EntityManager) {
      createNativeQuery(_) >> query
   }

   expect:
   manager.createNativeQuery("").setParameter(1,1).getResultList() == [1]
}