【问题标题】:How to create Spock Spy with private property如何使用私有财产创建 Spock Spy
【发布时间】:2018-04-13 13:29:44
【问题描述】:

我有以下 Java 类:

public class FooServiceImpl {
    private BarService barService;

    public String generateFoo() {
        String barValue = barService.generateBar();
        return customFoo() + barValue;
    }

    public String customFoo() {
       return "abc";
    }
}

这里是典型的 Spock 测试方法:

def "generate foo bar"() {
    setup:
        def barService = Mock(BarService) {
            generateBar() >> "Bar"
        }
        FooServiceImpl spyFooService = 
          Spy(FooServiceImpl, constructorArgs: [[barService: barService]])

        spyFooService.customFoo() >> "foo"
    when:
        def fooValue = spyFooService.generateFoo()
    then:
        fooValue == "fooBar"
}

我尝试为 FooServiceImpl 类创建 Spy 对象,但出现以下错误:

org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack: 
No such property: barService for class: 
com.foo.FooServiceImpl$$EnhancerByCGL`

我无法将构造函数添加到FooServiceImplBarService 的设置器,所以我想使用映射构造函数。这可能吗?

注意:根据this issue 它应该可以工作

【问题讨论】:

    标签: java groovy spock


    【解决方案1】:

    在您的情况下,最简单的解决方案是将此字段设为 protected 而不是 private。当您从一个类创建一个间谍对象时,CGLIB 会参与其中,它会从您尝试从中创建间谍的类创建为子类 - 在您的情况下是 com.foo.FooServiceImpl$$EnhancerByCGL。问题是您要修改的字段是私有字段,并且根据 Java 中的常规子类化策略,私有字段不会在子类中继承。这就是为什么间谍对象中不存在字段barService

    注意: IntelliJ 的调试器可能会告诉您 barService 存在于此 spyFromService 实例中,但这是 IDE 的错误 - 如果您列出来自 spyFromService.class.fieldsspyFromService.class.declaredFields 的所有可用字段你不会在这里找到barService 字段。

    另一个问题是,当 CGLIB 参与对象创建过程时,如果涉及到调用方法,它也会参与其中。这就是为什么通过 Groovy 的元编程功能向类或实例添加动态字段不起作用的原因。否则,您将能够执行以下操作:

    spyFromService.metaClass.barService = barService
    

    spyFromService.class.metaClass.barService = barService
    

    或者,您可以摆脱间谍对象并在测试中使用真实实例。那么

    FooServiceImpl spyFromService = new FooServiceImpl()
    spyFromService.@barService = barService
    

    会起作用。但是,您将无法存根现有的 customFoo() 方法,您将不得不依赖其实际实现返回的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2016-11-17
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多