【问题标题】:How to mock EntityManager and Query with Spock?如何使用 Spock 模拟 EntityManager 和查询?
【发布时间】:2017-05-11 18:09:19
【问题描述】:

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

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

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

我尝试将语句分解为单独的语句和附带的模拟,但这也没有奏效,因为我仍然得到一个空查询。

我不知道我现在是否有关于这方面的隧道视觉,或者这是否不能被嘲笑——至少对 Spock 来说是这样。

感谢所有帮助!

【问题讨论】:

    标签: unit-testing jpa spock


    【解决方案1】:

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

    查询:

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

    实体管理器:

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

    【讨论】:

    • 我喜欢模拟返回模拟的描述!不幸的是,我收到了关于无法在空对象上 setParameter 的错误。
    • @Les,请分享整个规范。
    • 只是一个猜测-它可能同时与这个答案(模拟和验证)有关:stackoverflow.com/questions/35059223/…
    • 我错了。我有一个错字。没有方法 createNativeQuery - 它是 createNamedQuery。一旦我纠正您的解决方案完美运行!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 2021-02-01
    • 1970-01-01
    • 2015-03-27
    • 2017-06-29
    • 2015-08-03
    • 2022-06-11
    • 1970-01-01
    相关资源
    最近更新 更多