闭包验证覆盖默认模拟

时间:2015-09-26 13:57:27

标签: spock

我的方法如下:

public void save(DbSession session,Wrappe wrapper,Wrappe wrappe){
      //...other logic

      //save wrapper
      wrapper=(Wrapper)session.save(wrapper)

      //set wrapper's id into wrappee
      wrappee.setWrapperId(wrapper.getId());

      //save wrappee
      session.save(wrappee);
}

并且测试代码如下所示:

    given:      
    session.save(_) >> wrapperWithGeneratedId

    when:
    obj.save(session,wrapper,wrappee)

    then:"wrapper got saved"
    1*session.save(_) >> {Wrapper save ->
         diffs(wrapper,saved)==null
    }
    and:"wrappee"
    1*session.save(_) >> {Wrappe saved ->
        diffs(wrappee,saved)==null
    }

这些测试代码会给出一个例外:

java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.company.model.Wrapper

如果在"中注释了验证结束,那么"部分,测试将通过,所以我猜这部分

1*session.save(_) >> {Wrapper save ->
         diffs(wrapper,saved)==null
}

超越了这个嘲弄:

session.save(_) >> wrapperWithGeneratedId

有没有办法正确做到?

1 个答案:

答案 0 :(得分:0)

第一。 '和'是语法糖。它只是一种在同一块中可视地分离代码的方法。你的最后两个嘲讽实际上是相同的(虽然你在行为上进行测试,它仍然会验证保存被调用两次。)

第二。假设您要验证diffs(wrapper,saved)==null,那当前不会发生,因为它不是'基准级'评估。如果你想评估它,那么/ then / closures / etc中的任何东西都需要在'assert'前加上。

第三。然后一个块的范围限定在它的阻塞时,可以覆盖现有的模拟;你假设你的模拟被覆盖是正确的。

第四。您是否有任何理由不仅仅在评估中包含您的回报值?

2 * session.save(_) >> {Wrapper save ->
     diffs(wrapper,saved)==null
     return wrapperWithGeneratedId
}

第五。您的错误是由于您的模型返回一个布尔值(您的断言逻辑),然后Groovy尝试(并失败)解析为Wrapper。我为什么会发生这种情况的假设是.save()的返回类型为Wrapper。要解决这个问题,您需要为Wrapper创建一个布尔构造函数,或者更改您的模型以返回Groovy可以变成Wrapper的东西(第4点中的操作方法)

Official Stub/Mock/Spy documentation (quite good, worth a read)