【问题标题】:Spock bug with testing private method?测试私有方法的Spock错误?
【发布时间】:2016-02-16 20:20:37
【问题描述】:

谁能告诉我这是一个错误还是预期的行为。

我知道在 Spock 中我可以测试私有方法:

def "test with private"() {
    given:
        FileContentValidator fileContentValidator = new FileContentValidator(1)

    when:
        fileContentValidator.validateCustomerSiteId("") // this is a private method

    then:
        true // succeeds
}

但是当我使用 Spock Spy 尝试同样的事情时,它失败了:

def "test with private on spy"() {
    given:
        FileContentValidator fileContentValidator = Spy(FileContentValidator, constructorArgs: [1])

    when:
        fileContentValidator.validateCustomerSiteId("") // this is a private method

    then:
        true // does not get here
}

我得到一个例外:

groovy.lang.MissingMethodException: No signature of method: com.shoppertrak.device.management.web.validator.ophour.FileContentValidator$$EnhancerByCGLIB$$7ff6a42.validateCustomerSiteId() is applicable for argument types: (java.lang.String) values: []

【问题讨论】:

  • 似乎轻率地将其称为错误。间谍的工作是窥探合约中的方法,这是一个灵活的概念,但很难找到包含声明为私有的东西的定义。
  • 那么也许将其归入“预期行为”类别
  • FileContentValidator 是类类型还是接口类型?间谍总是基于真实对象,您必须提供类类型而不是接口类型。
  • FileContentValidator 是一个类
  • 尝试将方法更改为受保护。

标签: java groovy spock


【解决方案1】:

我认为这是由于cglib 的工作原理。在测试现有的具体类时,Spock 不会涉及字节码,因此您正在利用 Groovy 中的一个缺陷,该缺陷使您可以访问私有方法。当您 spymock 同一个类时,Spock/cglib 操作会介入并更改生成的字节码。最终产品是一种真正私有的方法,因此您无法访问它。

您可能可以使用一些技巧来绕过它,但您最好添加类似 CustomerSiteIdValidator 的类和公共 validateCustomerSiteId() 注入到您的 FileContentValidator 类中。然后您可以轻松地模拟它并隔离职责。

有人建议将功能添加到 Spy 私有方法,但该票被关闭为 Won't Fix https://github.com/spockframework/spock/issues/403

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 2015-06-23
    • 2019-03-12
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2014-08-10
    相关资源
    最近更新 更多