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

Global mocking not working when receiving null on methods with many signatures #871

Closed
fogrizovic opened this issue Aug 15, 2018 · 7 comments · Fixed by #1134
Closed

Global mocking not working when receiving null on methods with many signatures #871

fogrizovic opened this issue Aug 15, 2018 · 7 comments · Fixed by #1134

Comments

@fogrizovic
Copy link

fogrizovic commented Aug 15, 2018

Hi,

I'm trying to stub a static method from Java class, which has more than one signature. Like this

def "test stubbing"() {
       given:
       GroovySpy(Foo, global: true)
       Foo.generate(_) >>  "bla"
       when:
       def res = Foo.generate((Obj1) null)
       then:
       res == "bla"
   }

Foo is a java class with mehtod "generate" defined as:

public static String generate(Obj1 obj) {
// somehting
}

public static String generate(Obj2 obj) {
// somehting
}

Then I'm getting:

groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method Foo#generate.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[Obj1]
[Obj2]

Is this the expected behaviour? How can I call generate with "null" value?

@postapczuk
Copy link

postapczuk commented Aug 17, 2018

You cannot stub method with two signatures in one stub. You need to precise which signature you are stubbing. Use Foo.generate(_ as Obj1) >> "bla1" and Foo.generate(_ as Obj2) >> " bla2" .

@fogrizovic
Copy link
Author

fogrizovic commented Aug 17, 2018

Hi @postapczuk

I also tried that, and I'm still getting the same. Tried this:

given: 
GroovySpy(Foo, global: true)
Foo.generate(_ as Obj1) >>  "bla"
Foo.generate(_ as Obj2) >>  "ble"
when:
def res = Foo.generate((Obj1) null)

@FatCash
Copy link

FatCash commented Mar 11, 2019

+1 Neither calling with generate(null as Obj1) or generate((Obj1) null) works 😕
Have you found any workaround to test with null argument when there is a method/constructor with more than one signature?

@postapczuk
Copy link

postapczuk commented Mar 17, 2019

What are you testing in your test?

It doesn't make sense:

First you're stubing:
Foo.generate(_) >> "bla"

And then you test this stub:
def res = Foo.generate((Obj1) null)

If you're testing the static method, you shouldn't do the stub.

If you're testing some class that is use Foo's static method you should change 'when' section to use method from that class, not from Foo.

@slyns
Copy link

slyns commented Mar 18, 2019

@fogrizovic , actually Foo.generate((Obj1) null) will not help Groovy to choose proper method. This might be more specific to Groovy itself, not Spock, see https://stackoverflow.com/questions/26037514/groovy-method-overloading-selection-of-method-prefers-interfaces-over-subclasse

@ssrinathraju
Copy link

I think You can't use GroovyMock for testing the Java static method.

The methods under MockingApi like GroovyMock, GroovySpy are specific to Groovy

Please refer the same in the Spock doc: http://spockframework.org/spock/docs/1.0/interaction_based_testing.html (Groovy Mocks (New in 0.7)

@Vampire
Copy link
Member

Vampire commented Mar 25, 2020

@ssrinathraju it depends.
The point is the code that is "calling" the mock, not the class that is mocked.
If the code that is tested calls a static method on a Java class, a GroovyMock can be used to mock this call.
And in this - I guess simplified - example the code that is tested is inlined in the feature method as Foo.generate((Obj1) null).
Imagine this line is in some Groovy file and that Groovy file is tested here, then the expectation of OP is fine.
If you e. g. replace Foo.generate((Obj1) null) by Foo.generate('foo'), the test is successful as the mock worked.

The problem ist most probably more how the mocks are implemented and that they don't carry over the cast to the method selection or something similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants