Spock mock verify returns 0 invocations

血红的双手。 提交于 2019-12-06 13:42:16

A simple answer would be don't use @Shared for mocks/stubs/spies.

@Shared def proc = new MyProcessor()

def test() {
    given:
    def log = Mock(LogService)
    proc.logService = log

    when:
    proc.process(new Object())

    then:
    1 * log.update(_)
}

Now the explanation: When you run your spec Spock creates a Specification instance for each test, plus, it creates a shared Specification instance to keep track of shared fields.

Look into org.spockframework.runtime.BaseSpecRunner and you will see two fields:

protected Specification sharedInstance;
protected Specification currentInstance;

Moreover, there are two specification contexts: shared and current. The context keeps the instance, mock context and a mock controller. Here goes the problem. As you declare your mock as shared it is bind to the shared mock controller, but when you declair interactions ('then:' block) Spock adds these interactions to the current mock controller. So when the mock method is invoked (e.g. logService.update(e)) Spock checks if this interaction is allowed with the shared mock controller, as you declare the mock as shared but finds nothing there, because you put the interaction in the current controller.

Don't use mock/stubs/spies as @Shared fields.

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