问题描述
我有一个奇怪的用例,当我不检查'then:'部分中对模拟类的两次调用时,spock模拟返回正确的值,但是当我在其中包括两次检查时,spock模拟返回0. 然后:"部分.这是模拟的:
I have got a strange use case where spock mock is returning the correct value when I do not check for two calls on the mocked class in the 'then:' section, but it is returning 0 when I include two checks in the 'then:' section.This is the mock:
mockDao.readCounter(_, _, _, _, _) >> dbValue
这是失败的"then:"部分:
and here is the 'then:' section that fails:
1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
在这种情况下,将返回"0"而不是"dbValue".但是,如果我注释掉这两个检查中的任何一个,则它会通过.因此,以下两种情况通过了:
In this case, instead of 'dbValue', '0' is returned. But if I comment out either of the two checks, then it passes. So, the following two cases pass:
//1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
OR
1 * mockDao.readCounter(_, _, _, _, _)
// updateCounters is called with: sum = dbValue + value
//1 * mockDao.updateCounter(namespace, date, key, min, shardID, dbValue + value)
这是spock的gradle部分:
Here is the gradle section for spock:
// spock
testCompile "org.codehaus.groovy:groovy:2.4.7"
compile group: 'org.spockframework', name: 'spock-core', version: '1.0-groovy-2.4'
// !!! To get none-interface base mocking to work with Spock
compile group: 'cglib', name: 'cglib-nodep', version: '3.2.4'
推荐答案
这是预期行为并已记录在案.如果要在同一模拟上进行模拟和存根,则必须像
This is expected and documented behavior. If you want to mock and stub on the same mock, you have to do it in one line like
1 * mockDao.readCounter(_, _, _, _, _) >> dbValue
在相关部分:
嘲讽与相伴相伴:
1 * subscriber.receive("message1") >> "ok"
1 * subscriber.receive("message2") >> "fail"
在模拟和存根相同的方法调用时,它们必须在相同的交互中发生.特别是,以下将Mockito样式的存根和模拟拆分为两个单独的语句的方法将不起作用:
When mocking and stubbing the same method call, they have to happen in the same interaction. In particular, the following Mockito-style splitting of stubbing and mocking into two separate statements will not work:
setup:
subscriber.receive("message1") >> "ok"
when:
publisher.send("message1")
then:
1 * subscriber.receive("message1")
如在何处声明交互中所述, receive
调用将首先与then:
块中的交互进行匹配.由于该交互未指定响应,因此将返回该方法的返回类型的默认值(在这种情况下为null
). (这只是Spock宽大的嘲笑方法的另一个方面.)因此,setup:
块中的交互将永远不会有匹配的机会.
As explained in Where to Declare Interactions, the receive
call will first get matched against the interaction in the then:
block. Since that interaction doesn’t specify a response, the default value for the method’s return type (null
in this case) will be returned. (This is just another facet of Spock’s lenient approach to mocking.). Hence, the interaction in the setup:
block will never get a chance to match.
注意 |相同的方法调用的模拟和存根必须在相同的交互中发生.
NOTE | Mocking and stubbing of the same method call has to happen in the same interaction.
这篇关于Spock模拟返回错误值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!