Search code examples
groovymockitoaopspy

Mockito Matchers in Groovy


I am experimenting with converting a project of mine to groovy and would like to carry on using JUnit4 with Mockito. I have a test which verifies that a spring aop around advice is called when I call a different method.

Here is my code:

 @Test
  void testPointCut() {
    //Given
    def target = new MainController();
    def factory = new AspectJProxyFactory(target);
    def aspect = mock(LoggingAspect.class);
    factory.addAspect(aspect);
    def proxy = factory.getProxy();
    when(aspect.log(any(ProceedingJoinPoint))).thenReturn(null);

    //When
    proxy.index();

    //Then
    verify(aspect).log(any(ProceedingJoinPoint));
  }

When I run this, I get an exception:

testPointCut(com.meetupinthemiddle.LoggingAspectTest)  Time elapsed: 0.277 sec  <<< ERROR!
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.

        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPogoSite(CallSiteArray.java:147)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:164)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at com.meetupinthemiddle.LoggingAspectTest.testPointCut(LoggingAspectTest.groovy:20)

But the equivalent code in Java works with no problem- Any ideas? I think the issue might the same as this? Bug in Mockito with Grails/Groovy but it doesn't have an answer!


Solution

  • I believe Mockito has trouble mocking concrete groovy classes. I get the same type of error when I mock a simple concrete classes, but when I add an interface and mock the interface then it works.

    I think (as stated in the answer to the question you linked to) that groovy is intercepting the call and replacing it will a call to getMetaClass().

    Possible evidence for this is that the error says "0 matchers expected" when you clearly have matches on your method.