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

Global Groovy mock doesn't work as expected #785

Open
flyingclamking opened this Issue Oct 27, 2017 · 1 comment

Comments

Projects
None yet
2 participants
@flyingclamking

flyingclamking commented Oct 27, 2017

Hello, I made a unit test example based on the documentation here:
http://spockframework.org/spock/docs/1.1/interaction_based_testing.html

Specifically, I am following the example under the section: Mocking All Instances of a Type

Here is my code:

package library
import spock.lang.Specification

class Publisher {
    def subscribers = []

    def send(event) {
        subscribers.each {
            it.receive(event)
        }
    }
}

interface Subscriber {
    def receive(event)
}

class RealSubscriber implements Subscriber {
    @Override
    def receive(Object event) {
        return null
    }
}


class PublisherSpec extends Specification {


    def "delivers events to all subscribers"() {
        given:
        def pub = new Publisher()
        def sub1 = Mock(Subscriber)
        def sub2 = Mock(Subscriber)
        pub.subscribers << sub1 << sub2

        when:
        pub.send("event")

        then:
        1 * sub1.receive("event")
        1 * sub2.receive("event")
    }

    def "test global mock"() {
        given:
        def pub = new Publisher()
        pub.subscribers << new RealSubscriber() << new RealSubscriber()
        def anySub = GroovyMock(RealSubscriber, global:true)

        when:
        pub.send("event")

        then:
        2 * anySub.receive("event")
    }
}

After running these 2 tests, the first one passes. However the second one failed with below error:

Too few invocations for:

2 * anySub.receive("event")   (0 invocations)

Unmatched invocations (ordered by similarity):

None



	at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:78)
	at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:76)
	at library.PublisherSpec.test global mock(PublisherSpec.groovy:51)

I would expect the second test passes as well, did I miss something in the test? Please help!

Here is my local env: (and I am using latest spock: spock-core:1.1-groovy-2.4-rc-3)

Gradle 4.2

Build time: 2017-09-20 14:48:23 UTC
Revision: 5ba503cc17748671c83ce35d7da1cffd6e24dfbd

Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_102 (Oracle Corporation 25.102-b14)
OS: Linux 4.10.0-35-generic amd64

@flyingclamking

This comment has been minimized.

Show comment
Hide comment
@flyingclamking

flyingclamking Oct 27, 2017

I also find a weird situation when I try to use global GroovySpy. I copied the unit test example here:
https://github.com/spockframework/spock/blob/master/spock-specs/src/test/groovy/org/spockframework/smoke/mock/GroovySpiesThatAreGlobal.groovy
and I modify it a litter bit.
Here is my code example:

    def "mock dynamic instance method called via MOP and it doesn't work"() {
        def person = new Person()
        def anyPerson = GroovySpy(Person, global: true)

        when:
        person.invokeMethod("foo", [42] as Object[])

        then:
        1 * anyPerson.foo(42) >> "done"
    }

The above test case failed which gives me this error:

groovy.lang.MissingMethodException: No signature of method: static library.GroovySpiesThatAreGlobal.foo() is applicable for argument types: (java.lang.Integer) values: [42]
Possible solutions: Mock(), Spy(), any(), find(), Mock(groovy.lang.Closure), Mock(java.lang.Class)

at library.GroovySpiesThatAreGlobal.mock dynamic instance method called via MOP and it doesn't work(GroovySpiesThatAreGlobal.groovy:125)

The only thing I changed is the order of mock and actual creation of the instance. Can someone explain why this test case fails?

flyingclamking commented Oct 27, 2017

I also find a weird situation when I try to use global GroovySpy. I copied the unit test example here:
https://github.com/spockframework/spock/blob/master/spock-specs/src/test/groovy/org/spockframework/smoke/mock/GroovySpiesThatAreGlobal.groovy
and I modify it a litter bit.
Here is my code example:

    def "mock dynamic instance method called via MOP and it doesn't work"() {
        def person = new Person()
        def anyPerson = GroovySpy(Person, global: true)

        when:
        person.invokeMethod("foo", [42] as Object[])

        then:
        1 * anyPerson.foo(42) >> "done"
    }

The above test case failed which gives me this error:

groovy.lang.MissingMethodException: No signature of method: static library.GroovySpiesThatAreGlobal.foo() is applicable for argument types: (java.lang.Integer) values: [42]
Possible solutions: Mock(), Spy(), any(), find(), Mock(groovy.lang.Closure), Mock(java.lang.Class)

at library.GroovySpiesThatAreGlobal.mock dynamic instance method called via MOP and it doesn't work(GroovySpiesThatAreGlobal.groovy:125)

The only thing I changed is the order of mock and actual creation of the instance. Can someone explain why this test case fails?

@leonard84 leonard84 added the bug label Jul 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment