I am trying to write a unit test for a class that uses Google's vision API with the AnnotatorImageClient
from the google-cloud-vision
lib.
The problem is that my mocked AnnotatorImageClient
for some reason still calls the real batchAnnotateImages
method and then throws a NPE, which breaks my test.
I have never seen this behavior on a mock before and I'm wondering if I'm doing something wrong, if there is a bug in spock/groovy or if it has something to do with that Google lib?
I have already checked if the object used in my class is really a mock, which it is. I have tried with Spock version 1.2-groovy-2.5 and 1.3-groovy.2.5
The class that is tested:
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)));
}
The test:
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()
}
}
I would expect the mock to simply return null
(I know that this test doesn't make a lot of sense). Instead, it calls com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages
which throws an NPE.