Unit testing 如何使用Spock模拟EntityManager和查询?

Unit testing 如何使用Spock模拟EntityManager和查询?,unit-testing,jpa,spock,Unit Testing,Jpa,Spock,使用spock我需要模拟对EntityManager的调用/Query。我试图模拟的代码行是: entityManager.createNativeQuery("nativeQuery").setParameter(1, param1).getResultList() entityManager.createNativeQuery的模拟返回一个nullQuery对象。这会导致失败,因为您无法对空对象调用方法。因此,我不能模拟结果集列表的返回 我曾尝试将语句分解为单独的语句和相应的模拟语句,但这

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

entityManager.createNativeQuery("nativeQuery").setParameter(1, param1).getResultList()
entityManager.createNativeQuery
的模拟返回一个null
Query
对象。这会导致失败,因为您无法对空对象调用方法。因此,我不能模拟结果集列表的返回

我曾尝试将语句分解为单独的语句和相应的模拟语句,但这也不起作用,因为我仍然会得到一个空查询

我不知道我现在是不是在这件事上有隧道视觉,或者这件事不能被嘲笑——至少对斯波克来说是这样


感谢大家的帮助

您需要做的是构建一个模拟层次结构,从最后一个开始,这些模拟将相互返回:

查询:

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

def manager = Mock(EntityManager) {
   createNativeQuery(_) >> query
}
等等。虽然您需要实现的东西是可行的,但它或多或少表明设计不好:每次mock返回一个mock时,一个仙女就死了,所以您应该避免这样的构造。您可以做的是将查询构建和它的执行分开,这样模拟就容易多了。样本规格:

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]
}

我喜欢描述一个模拟返回模拟!不幸的是,我遇到了一个错误,就是无法在空对象上设置参数。@Les,请分享整个规范。只是一个猜测-它可能与这个答案(模拟和验证)同时相关:我错了。我打错了。没有方法createNativeQuery-它是createNamedQuery。有一次我纠正了你的解决方案非常有效!谢谢