rao*_*son 14 groovy unit-testing programming-languages dynamic-languages mocking
我有一个POJO使用服务来做某事:
public class PlainOldJavaObject {
private IService service;
public String publicMethod(String x) {
return doCallService(x);
}
public String doCallService(String x) {
if(service == null) {
throw new RuntimeException("Service must not be null");
}
return service.callX(x);
}
public interface IService {
String callX(Object o);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个Groovy测试用例:
class GTest extends GroovyTestCase {
def testInjectedMockIFace() {
def pojo = new PlainOldJavaObject( service: { callX: "very groovy" } as IService )
assert "very groovy" == pojo.publicMethod("arg")
}
def testMetaClass() {
def pojo = new PlainOldJavaObject()
pojo.metaClass.doCallService = { String s ->
"no service"
}
assert "no service" == pojo.publicMethod("arg")
}
}
Run Code Online (Sandbox Code Playgroud)
第一个测试方法testInjectedMockIFace按预期工作:POJO是使用动态实现创建的IService.当callX被调用时,它只是返回"很时髦".这样,服务就被嘲笑了.
但是我不明白为什么第二种方法testMetaClass不能按预期工作,而是在尝试调用callX服务对象时抛出NullPointerException .我以为我doCallService用这一行覆盖了这个方法:
pojo.metaClass.doCallService = { String s ->
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢!
noa*_*oah 18
如果您的POJO确实是Java类,而不是Groovy类,那么这就是您的问题.Java类不通过metaClass调用方法.例如,在Groovy中:
pojo.publicMethod('arg')
Run Code Online (Sandbox Code Playgroud)
相当于这个Java:
pojo.getMetaClass().invokeMethod('publicMethod','arg');
Run Code Online (Sandbox Code Playgroud)
invokeMethod通过metaClass发送调用.但这种方法:
public String publicMethod(String x) {
return doCallService(x);
}
Run Code Online (Sandbox Code Playgroud)
是一种Java方法.它不invokeMethod用于打电话doCallService.要使代码工作,PlainOldJavaObject需要是一个Groovy类,以便所有调用都将通过metaClass.普通Java代码不使用metaClasses.
简而言之:即使Groovy也不能覆盖Java方法调用,它只能覆盖来自Groovy的调用或者通过invokeMethod调度.
l15*_*15a 18
你的语法有点偏.问题是pojo是一个Java对象,没有metaClass.使用ExpandoMetaClass拦截对PlainOldJavaObject的doCallService的调用:
只需更换:
pojo.metaClass.doCallService = { String s ->
"no service"
}
Run Code Online (Sandbox Code Playgroud)
附:
PlainOldJavaObject.metaClass.doCallService = { String s ->
"no service"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23242 次 |
| 最近记录: |