我正在尝试使用一些Groovy优点来扩充现有的Java项目,从测试开始。 所以,假设我有依赖ServiceB(另一个Java类)的ServiceA(Java类);它在构造函数中作为引用传递:
public class ServiceA {
private ServiceB serviceB;
public ServiceA(ServiceB seviceB){
this.serviceB = serviceB;
}
public boolean doSomeWork(){
//some logic
return serviceB.doMoreWork();
}
}
假设serviceB.doMoreWork()返回true
。
为了测试ServiceA,我想使用MockFor模拟ServiceB:
@Test
void testDoSomeWork(){
def mocker = new MockFor(ServiceB) //1 create the Mock support
mocker.demand.doMoreWork(2){ //2 twice for this demonstration
false //3 return other value than in real code
}
mocker.use {
def mockServiceB = new ServiceB() //4 creates mock instead of real one
assert !mockServiceB.doMoreWork() //5 that's good!
def serviceA = new ServiceA(mockServiceB)
assert !serviceA.doSomeWork() //6 that fails! Real implementation called!
}
}
正如您所看到的,同一个对象在#5中充当模拟,在#6中充当真实对象。我认为它与Java对象有关,而不是GoovyObject。是什么给了什么?
谢谢!
巴鲁。
答案 0 :(得分:1)
你不是在这里创造模拟。您正在创建真实对象。这是Groovy以不同方式路由的方法调度。
2)在下面的代码中,Groovy负责将doMoreWork()调用路由到mock版本,因为“new MockFor(ServiceB).demand.doMoreWork”为Groovy提供了有关doMoreWork()的存根实现的信息。 / p>
def mocker = new MockFor(ServiceB) mocker.use { mockServiceB.doMoreWork() }
因此,当使用Groovy进行mockServiceB.doMoreWork()调用时,上述魔法会起作用。
当从Java进行相同的调用时,它不会通过Groovy的MOP基础结构,因此它直接进入doMoreWork()的实际实现
请记住:对于MockFor,Groovy不会执行任何字节码检测等,以便修改后的类在Java中也可见。