Java Groovy Spock模拟调用模拟类的实方法

Java Groovy Spock模拟调用模拟类的实方法,java,groovy,mocking,spock,vision-api,Java,Groovy,Mocking,Spock,Vision Api,我正在尝试为一个类编写一个单元测试,该类使用Google的vision API和AnnotatorImageClient,该类来自Google cloud visionlib。 问题是我的mockAnnotatorImageClient出于某种原因仍然调用realbatchAnnotateImages方法,然后抛出一个NPE,这破坏了我的测试。 我以前从未在mock上见过这种行为,我想知道我是否做错了什么,spock/groovy中是否有bug,或者它是否与Google库有关 我已经检查了我的类

我正在尝试为一个类编写一个单元测试,该类使用Google的vision API和
AnnotatorImageClient
,该类来自
Google cloud vision
lib。 问题是我的mock
AnnotatorImageClient
出于某种原因仍然调用real
batchAnnotateImages
方法,然后抛出一个NPE,这破坏了我的测试。 我以前从未在mock上见过这种行为,我想知道我是否做错了什么,spock/groovy中是否有bug,或者它是否与Google库有关

我已经检查了我的类中使用的对象是否真的是一个mock,事实确实如此。我已经尝试过Spock版本1.2-groovy-2.5和1.3-groovy.2.5

被测试的类:

public class VisionClient {

    private final ImageAnnotatorClient client;

    @Autowired
    public VisionClient(final ImageAnnotatorClient client) {
        this.client = client;
    }

    public Optional<BatchAnnotateImagesResponse> getLabelsForImage(final Image image) {
        var feature = Feature.newBuilder().setType(LABEL_DETECTION).build();

        var request = AnnotateImageRequest.newBuilder()
                .addFeatures(feature)
                .setImage(image)
                .build();

        return Optional.ofNullable(client.batchAnnotateImages(singletonList(request)));
}

我希望mock只返回
null
(我知道这个测试没有多大意义)。相反,它调用
com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages
,抛出一个NPE。

ImageAnnotatorClient
是用Java编写的,方法
batchAnnotateImages(要获得您需要的内容,列表是如何让它与Spock一起工作的教程。

在我的例子中,我必须通过此导入使用
SpringBean
注释模拟字段


import org.spockframework.spring.SpringBean

尝试使用
\u
-似乎参数
\uu作为列表
没有正确匹配?我也尝试了
\u
,但仍然得到了相同的结果。即使我完全使用stubing,结果仍然是一样的:调用real方法,NPE是抛出。但是可以更改修饰符@Jazzschmidt是的,你是对的,反射是第二个选择。非常感谢你为我指出了正确的方向!groovy似乎确实对那些本身不是final但包含final方法的类有问题。我通过在我的类和他
ImageAnnotatorClient
,只是作为代理,Spock可以毫无问题地模仿他。我在Kotlin中遇到了类似的问题,因为该方法没有标记关键字“open”。此响应为我提供了正确的线索:),所以请注意这一点,以防您使用Kotlin。
class VisionClientSpec extends Specification {
    def "The client should use Google's client to call Vision API"() {
        given:
        def googleClientMock = Mock(ImageAnnotatorClient)
        def visionClient = new VisionClient(googleClientMock)
        def imageMock = Image.newBuilder().build()

        when:
        def resultOpt = visionClient.getLabelsForImage(imageMock)

        then:
        1 * googleClientMock.batchAnnotateImages(_ as List) >> null
        !resultOpt.isPresent()
    }
}