【问题标题】:How to Mock private variable in Grails in spock framework如何在 spock 框架中模拟 Grails 中的私有变量
【发布时间】:2020-12-21 13:05:36
【问题描述】:

我的目标是Mock Grails 中服务类方法中的私有变量。

在这里,我在测试方法中尝试了以下方式:

given: 'Mocking of object'
        def dataSource = Mock(TransactionAwareDataSourceProxy)
        def db1 = Mock(Sql)
        service.dataSource = dataSource

        new Sql(dataSource) >> db1

    List<GroovyRowResult> resultList = new ArrayList<>()
    GroovyRowResult result = new GroovyRowResult(id: 0)
    result.someAmount = 400
    resultList.add(result)

    db1.rows(_) >> resultList

在我的服务类中,我的代码是:

def db = new Sql(dataSource)
List<GroovyRowResult> resultList = db.rows("Select * from user_info")

在这里,我成功地模拟了名为 dataSource 的 TransactionAwareDataSourceProxy,但我未能将模拟 def db = new Sql(dataSource) 分配给本地私有变量 db。

我需要以下解决方案

  1. 如何在方法中模拟私有变量。在这里,我在我的服务方法中的私有变量db 中分配Sql

提前致谢

【问题讨论】:

    标签: sql unit-testing grails spock


    【解决方案1】:

    简单的答案是:你不知道。相反,您重构以能够使用依赖注入,即将Sql 实例传递给方法或类。然后你就可以轻松地模拟它了。

    另请参阅here 以及与该答案相关的其他答案。


    我确实推荐“孩子们不要在家里这样做”部分,因为它仅适用于正在测试的 Groovy 类,并且还有助于在您的应用程序代码中建立不良设计:您可以使用 Spock 的 Groovy 模拟以 mock constructors。您可以使用 Mockito、Powermock 或我自己的工具 Sarek 为 Java 类实现相同的目标。 Sarek 甚至适用于 JRE 引导类,也是最终类。

    但是,当您在编写 Spock 测试时需要 Groovy 模拟或特殊的附加工具时,通常表明您应该进行重构。只有在您需要在无法修改的第三方代码中模拟某些内容的极少数情况下,您才可能需要此类工具。但即便如此,您通常也可以重构您自己的代码,以便以这样一种方式访问​​第三方代码,即您可以注入正确类型的测试替身(模拟、存根、间谍),并预先配置为您需要的行为。

    【讨论】:

      猜你喜欢
      • 2018-08-24
      • 1970-01-01
      • 2022-09-25
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多