If you mock and stub the same call, you have to do it in one interaction; you can't (and don't have to!) split up mocking and stubbing into two interactions. Same as EasyMock, JMock, etc., but different compared to Mockito.
Cheers,
Peter
> --
> You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
> To post to this group, send email to spockfr...@googlegroups.com.
> To unsubscribe from this group, send email to spockframewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.
>
On 14.10.2011, at 09:27, alpheratz wrote:
> OK. Thanks.
>
> So this works:
>
> ---
> def "test"() {
> setup:
> def grader = new Grader2(expectedAnswers: ['a','b','c'])
> def graderFileReader = Mock(GraderFileReader)
> //1 * graderFileReader.readGradesListFromFile(_) >>
> ['a','b','c']
> grader.graderFileReader = graderFileReader
>
> when:
> def res = grader.grade('100pct.txt')
>
> then:
> res == 1.0D
> 1 * graderFileReader.readGradesListFromFile(_) >>
> ['a','b','c']
> }
> ---
>
> It seems 'backwards' to me, still.
>
> It appears that the then: section is establishing the behaviour for
> readGradesListFromFile before execution begins as well as providing
> the assertion check at the end of execution.
>
> Is this correct?
Well, "1 * foo.bar()" isn't an assertion, at least not in the classical sense. It just _declares_ an expected interaction. The verification will happen at other points.
> If so, when would it be even _possible_ to have an interaction in the
> setup part...
Technically, an interaction _must_ be declared in the setup-block. This is how most mocking frameworks work (except for Mockito). Spock additionally allows an interaction to be declared in the then-block, because this is a more natural way to think about it. (After all, the interaction occurs after the stimulus in the when-block.) However, what happens internally is that this declaration gets moved to the setup-block, because the mocking framework needs to have all information up front.
> Any flow-of-control I postulate seems odd: 'res ==' MUST come
> cronologically after the call to 'grade()' but the '1 *
> graderFileReader.readGradesListFromFile' stuff MUST be in place before
> the call to 'grade()'
It would be more idiomatic to reorder the statements in the then-block so that interactions come before assertions. This is a more natural way to think about it. But Spock doesn't care; it will move all interactions from the then-block to the setup-block. To be more precise, it moves them to right before the corresponding when-block. If you find this confusing, just declare everything in the setup-block. This is what people are used to from EasyMock/JMock.
> And why is my situation apparently quite different to Ken Kousen's
> "The right way to mock a Klingon" at
> http://kousenit.wordpress.com/2011/08/20/i-think-i-get-spock-mocks-now/
> or the emailService example at
> http://www.intelligrape.com/blog/2011/04/07/interaction-based-testing-using-spock-in-grails/?
Not sure what you mean by that.
Cheers,
Peter