java - Groovy Spock 模拟调用模拟类的真实方法

标签 java groovy mocking spock vision-api

我正在尝试为一个类编写单元测试,该类使用 Google 的视觉 API 和 google-cloud-vision 库中的 AnnotatorImageClient。 问题是我模拟的 AnnotatorImageClient 出于某种原因仍然调用真正的 batchAnnotateImages 方法然后抛出 NPE,这破坏了我的测试。 我以前从未在模拟中看到过这种行为,我想知道我是否做错了什么,spock/groovy 中是否存在错误,或者它是否与该 Google 库有关?

我已经检查过我的类中使用的对象是否真的是一个模拟对象,它确实是。我已经尝试使用 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)));
}

测试:

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()
    }
}

我希望模拟简单地返回 null(我知道这个测试没有多大意义)。相反,它会调用引发 NPE 的 com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages

最佳答案

ImageAnnotatorClient是用Java写的,方法batchAnnotateImages(List<AnnotateImageRequest> requests)final .

Spock 能够模拟 Java final 类,但在模拟 Java final 方法方面不是很好。

您可以使用 PowerMock得到你需要的,here是如何让它与 Spock 一起工作的教程。

关于java - Groovy Spock 模拟调用模拟类的真实方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55568798/

相关文章:

python - 模拟对同一方法的多次调用时如何断言调用顺序和参数?

node.js - 使用 Jest 测试框架调用 fetch(url) 时,如何根据 url 模拟变量响应?

Groovy 代表按预期工作?

groovy - 通过 REST API 进行的 Artifactory 搜索导致 "Bad request"错误

hibernate - 如何在 Grails 中创建 "view"域对象

java - Java中带有时间戳的数字签名

ruby - Mocha 预计最多一次,调用两次,但方法显然只调用一次

java - 这个属性文件和 "include"其他属性文件到底是如何工作的?

java - Jenkins 测试失败

JavaFX 媒体播放器仅播放一秒的 MP3