我正在尝试为使用Jersey来访问RESTful Web服务的一些代码编写一些单元测试,并使用Mockito来模拟一些东西。这是我的代码:
@Test
void test() {
given:
// WebResource is a Jersey/JAX-RS construct.
WebResource mockResource = Mockito.mock(WebResource)
// Address.groovy is a POJO from my project.
Address mockAddress = Mockito.mock(Address)
// THE NEXT LINE IS WHAT IS THROWING THE EXCEPTION:
Mockito.when(mockResource.get(Mockito.any())).thenReturn(mockAddress)
when:
<omitted for brevity>
then:
<omitted for brevity>
}
正如您所看到的,每当mockAddress
尝试执行HTTP GET时,我尝试强制Jersey返回WebResource
实例。
当这个运行时,我得到:
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method com.sun.jersey.api.client.WebResource$$EnhancerByMockitoWithCGLIB$$1c2e51fa#get.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class com.sun.jersey.api.client.GenericType]
[class java.lang.Class]
at groovy.lang.MetaClassImpl.chooseMostSpecificParams(MetaClassImpl.java:3031)
at groovy.lang.MetaClassImpl.chooseMethodInternal(MetaClassImpl.java:2983)
at groovy.lang.MetaClassImpl.chooseMethod(MetaClassImpl.java:2926)
at groovy.lang.MetaClassImpl.getMethodWithCachingInternal(MetaClassImpl.java:1203)
at groovy.lang.MetaClassImpl.createPojoCallSite(MetaClassImpl.java:3130)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPojoSite(CallSiteArray.java:129)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:163)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at com.me.myapp.MyUnitTest.test(MyUnitTest.groovy:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
<large stack trace omitted for brevity>
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
MyUnitTest.groovy:19
是哪一行:
Mockito.when(mockResource.get(Mockito.any())).thenReturn(mockAddress)
关于发生了什么的任何想法?
答案 0 :(得分:4)
WebResource's get()
method is overloaded with get(Class)
and get(GenericType)
正如消息中所描述的那样,模糊性似乎就在哪里。话虽如此,使用Mockito.any()
似乎并不合适。我不是Mockito的大用户,因此我不知道使用它的正常使用情况。当我尝试将它与Java一起使用时,我会收到编译错误,因为Mockit.any()
将返回Object
,并且两个重载方法都不接受Object
作为参数。< / p>
话虽如此,您所嘲笑的行为是,当您在get
上致电WebResource
时,它应该返回Address
个对象,因此您会想要传递Address.class
(或者在Groovy的情况下Address
可能没问题,正如您在上一篇文章中提到的那样)get
方法。
应该起作用的东西(至少在我用Java测试时)是这样的:
WebResource resource = Mockito.mock(WebResource.class);
Address address = Mockito.mock(Address.class);
Mockito.when(resource.get(Address.class)).thenReturn(address);
Mockito.when(address.toString()).thenReturn("Hello World");
Address a = resource.get(Address.class);
System.out.println(a);
这应打印出"Hello World"
答案 1 :(得分:0)
这是由于Groovy中的multiple dispatch机制造成的。
只需将CFRunLoopRun()
调用的结果转换为要存根的重载方法的参数类型即可。
any()
进口:
when(mockResource.get(any() as Address)).thenReturn(mockAddress)
// this also works
when(mockResource.get(any(Address) as Address)).thenReturn(mockAddress)