Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot specify interactions in both setup/given and then. #251

Closed
robfletcher opened this issue Aug 30, 2015 · 6 comments
Closed

Cannot specify interactions in both setup/given and then. #251

robfletcher opened this issue Aug 30, 2015 · 6 comments

Comments

@robfletcher
Copy link
Contributor

Originally reported on Google Code with ID 129

What steps will reproduce the problem? If possible, provide source code and
stack trace.

package com.mayabansi.webapp.service.spock

import spock.lang.Specification

class OrderProcessServiceSpec extends Specification {

    def "Mock and give cardinality in setup: ONLY works"() {
        given:
            List<Integer> l = Mock()
            1 * l.get(0) >>  2;

        when:
            int i = l.get(0);

        then:
            i == 2
    }

    def "Mock and give cardinality in then: ONLY works"() {
        given:
            List<Integer> l = Mock()

        when:
            int i = l.get(0);

        then:
            1 * l.get(0) >>  2;
            i == 2
    }


    def "Mock, stub in given and check cardinality in interactions does not work"()
{
        given:
            List<Integer> l = Mock()
            l.get(0) >>  2;

        when:
            int i = l.get(0);

        then:
            1 * l.get(_)
            i == 2
    }
}

Stack trace:

Condition not satisfied:

i == 2
| |
| false
null

at com.mayabansi.webapp.service.spock.OrderProcessServiceSpec.Mocking and checking
interactions does not work(OrderProcessServiceSpec.groovy:56)


Process finished with exit code 255

What version of Spock and Groovy are you using?

<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>0.4-groovy-1.6</version>
<scope>test</scope>

Please provide any additional information below. You can also assign
labels.

Linux Mint
Java > 1.6
Groovy > 1.6 (based on Maven I believe)
Spock > 0.4 (based on Maven I believe)
IntelliJ Idea X IU-96.802


Reported by ravi.hasija on 2010-09-28 00:02:55


- _Attachment: [OrderProcessServiceSpec.groovy](https://storage.googleapis.com/google-code-attachments/spock/issue-129/comment-0/OrderProcessServiceSpec.groovy)_
@robfletcher
Copy link
Contributor Author

This is expected because interactions specified in a then-block currently have precedence
over interactions specified elsewhere. And because the interaction in the then-block
doesn't specify a return value, the default value for the mocked method's return type
(null in this case) is returned.

Does this behavior cause you any troubles? In general, you shouldn't (have to) specify
overlapping interactions (i.e. interactions that match the same calls).

Reported by pniederw on 2010-09-28 00:16:14

@robfletcher
Copy link
Contributor Author

Dear Peter,

Beautiful. I completely agree with your reasoning. If Spock will allow overlapping
interaction(s) in both setup and then, that may cause confusion and redundancy.

I was researching online and came across this: http://meetspock.appspot.com/?id=16001

There is a spec: "Mocking and checking interaction works"() on line number 15. Looking
at it I thought it is possible to have same interaction in given and then, kind of
like Mockito.

Consider this issue closed. I like your explanation, may be we can specify it in the
Wiki if it is not already done.

Conversely, I am presenting on Mockito and Spock tomorrow http://www.sunjug.org/september-2010.
Let me know if you would like information on it like the demo project on Git for your
documentation purposes etc.


Reported by ravi.hasija on 2010-09-28 01:40:17

@robfletcher
Copy link
Contributor Author

>If Spock will allow overlapping interaction(s) in both setup and then, that may cause
confusion and redundancy.

Technically, Spock does allow this, but one interaction will always "win". If the stubbed
interaction is found first (see below for search order), it will always match (as it
has no cardinality), and the other interaction won't ever get a chance to match. If
the mocked interaction is found first, it will match until the expected number of invocations
has been reached; the next call will cause a TooManyInvocationsError. (By the way,
the exception name is stolen from Mockito).

Search order for interactions is:
1. then-block
2. setup method
3. spec method (e.g. setup-block)

The main reason why then-blocks come first is to allow you to override interactions
specified, say, in a setup method. I'm not 100% sure this is the right decision, but
that's how it works at the moment.

Many people think that Spock's mocking framework works like Mockito because it also
allows to specify interactions after the fact. But in reality, it works more like EasyMock
and JMock. That is, the interactions must be known beforehand. Spock achieves this
by moving interactions in then-blocks before the corresponding when-block (at compile
time). Compared to Mockito, this has advantages (e.g. a single interaction can be used
for mocking AND stubbing) and drawbacks (if you factor out interactions into a helper
method and insist on calling the helper method from a then-block, you have to wrap
the call with "interaction { ... }" to help Spock understand that the helper method
contains interactions).

>Looking at it I thought it is possible to have same interaction in given and then,
kind of like Mockito.

Yeah, that example gives a wrong impression (it was written by someone else).

>I like your explanation, may be we can specify it in the Wiki if it is not already
done.

The documentation is definitely lacking, in particular for the mocking framework. We'll
work on this for 0.5/0.6.

>Conversely, I am presenting on Mockito and Spock tomorrow http://www.sunjug.org/september-2010.
Let me know if you would like information on it like the demo project on Git for your
documentation purposes etc.

Cool! I'd definitely like to see your presentation. By the way, for people who don't
want to give up on Mockito, there is also the option of using it together with Spock,
enjoying Spock's other benefits.

Reported by pniederw on 2010-09-28 03:30:39

@robfletcher
Copy link
Contributor Author

Reported by pniederw on 2010-09-28 03:31:45

  • Status changed: WontFix

@robfletcher
Copy link
Contributor Author

I will be blog my presentation and I will send you the link. The code is on GitHub.
Need to clean it up a little bit, before I show it to you :-)

Also, I tried to use Mockito and Spock in same project. I couldn't. Mockito doesn't
seem to work beyond JUnit 4.4 and Spock needs Junit 4.7. I am using Maven on my project
and I am a noob to Maven. So I could be doing something wrong. Your thoughts? Any way
is there a way I can get in touch with you directly? Don't want to spam your issue
comment section with irrelevant comments!!

Reported by ravi.hasija on 2010-09-29 02:45:26

@robfletcher
Copy link
Contributor Author

I think the JUnit version problem can be solved. The best place to discuss such things
is the Spock forum: http://forum.spockframework.org

Reported by pniederw on 2010-09-29 09:27:22

BoukeNijhuis added a commit to BoukeNijhuis/spock that referenced this issue Sep 26, 2020
By default Spock uses a match first algorithm to determine the defined return value of a method. So whenever there are multiple defined return values, it will pick the first (that is not exhausted). This change enables a user to change this to a match last algorithm. So Spock will pick the last defined return value (that is not exhausted). This enables easy overriding of default return values. As requested in issue spockframework#26, spockframework#251, spockframework#321 and spockframework#962.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant