cyrusinnovation / mockito-groovy-support

A library for making Mockito work with Groovy
MIT License
34 stars 17 forks source link

InvalidUseOfMatchersException when using ArgumentMatchers #1

Closed ghost closed 11 years ago

ghost commented 12 years ago

Thanks for setting this up -- I wasn't looking forward to going back to a record/play test paradigm!

But: I've got a Groovy class of the form:

class FooService {
    String getMessage(Bar bar) {
        ....
    }
}

When I mock this with a concrete Bar argument, it works fine. But when I try to say something like:

when(fooService.getMessage(any(Bar.class)).thenReturn(...)

I get an InvalidUseOfMatchersException. Stepping into the Mockito code with the debugger, it looks like the problem is that MatchersBinder.validateMatchers() thinks the invocation is fooService.getMetaClass() rather than fooService.getMessage(). Is this a known issue?

moss commented 12 years ago

Sorry I missed this earlier! It's not a known issue. I'll take a look at it and see what I can do.

ghost commented 12 years ago

Cool, thanks! If I submit any more bugs I'll try to do it in the form of a test. :)

Darkvater commented 12 years ago

Hi,

Is this issue easy to fix? If you give us some pointers we'd be happy to fix it. We are using Groovy heavily in our testing and it's quite annoying not to be able to use matchers.

Darkvater commented 11 years ago

Does this work together with MockitoConfiguration? I copied test MockingAGroovyClassFromGroovyTest, and now they all pass indeed. However, when the gmock(SomeGroovyClass) in the @Before is changed to Mockito.mock(SomeGroovyClass), as it should be possible after adding the MockitoConfiguration class, both tests fail.

shouldBeAbleToStubAMethodUsingAnArgumentMatcher
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded.

shouldBeAbleToVerifyAMethodOnAGroovyClass
org.mockito.exceptions.verification.TooManyActualInvocations: 
someGroovyClass.getMetaClass();
Wanted 1 time:
-> at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPogoSite(CallSiteArray.java:144)
But was 2 times. Undesired invocation:
-> at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
moss commented 11 years ago

Doesn't work with MockitoConfiguration right now, since it depends on things we can't configure from there. Mockito 1.9.5 adds an extension point that should work for this -- I'm currently experimenting with it.

Darkvater commented 11 years ago

I have made some changes to MockitoConfiguration with implementing a special groovyfied AnnotationEngine. That works perfectly with mocks created through the annotations (@Mock, @Spy, @InjectMocks, etc.) just not when you call Mockito.mock() yourself. I guess if the new version of Mockito adds an extension point there is no point in further exploring this. I will try to upload my changes next week though.

[Edit] ah, do you mean MockMaker? I just updated from 1.8.5 and saw this. [Edit] it looks easy, check if class is groovy in custom MockMaker and then add the gmock interceptor filter :)

moss commented 11 years ago

If you download the latest version, it should now just work with Mockito.mock() -- no need to use gmock or MockitoConfiguration or anything.