传递用Groovy的MockFor创建的模拟作为参考

时间:2011-03-08 05:22:08

标签: unit-testing groovy

我正在尝试使用一些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。是什么给了什么?

谢谢!

巴鲁。

1 个答案:

答案 0 :(得分:1)

1)以下理解是错误的:

def mockServiceB = new ServiceB()// 4创建mock而不是real

你不是在这里创造模拟。您正在创建真实对象。这是Groovy以不同方式路由的方法调度。

2)在下面的代码中,Groovy负责将doMoreWork()调用路由到mock版本,因为“new MockFor(ServiceB).demand.doMoreWork”为Groovy提供了有关do​​MoreWork()的存根实现的信息。 / p>

def mocker = new MockFor(ServiceB) mocker.use {      mockServiceB.doMoreWork() }

因此,当使用Groovy进行mockServiceB.doMoreWork()调用时,上述魔法会起作用。

当从Java进行相同的调用时,它不会通过Groovy的MOP基础结构,因此它直接进入doMoreWork()的实际实现

请记住:对于MockFor,Groovy不会执行任何字节码检测等,以便修改后的类在Java中也可见。