Java Groovy Spock模拟调用模拟类的实方法
我正在尝试为一个类编写一个单元测试,该类使用Google的vision API和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库有关 我已经检查了我的类
AnnotatorImageClient
,该类来自Google cloud vision
lib。
问题是我的mockAnnotatorImageClient
出于某种原因仍然调用realbatchAnnotateImages
方法,然后抛出一个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()
}
}