Spock mock returns wrong value

只愿长相守 提交于 2019-12-07 09:59:48

问题


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

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)

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)

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'

回答1:


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

Here the relevant section:

Combining Mocking and Stubbing

Mocking and stubbing go hand-in-hand:

1 * subscriber.receive("message1") >> "ok"
1 * subscriber.receive("message2") >> "fail"

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")

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.



来源:https://stackoverflow.com/questions/41841668/spock-mock-returns-wrong-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!