Skip to content

Groovy 3.0 internal methods are not ignored as they should be #2204

@rtandy

Description

@rtandy

Hello,

The following test passes with Groovy 2.4 and 2.5, and fails with Groovy 3.0 (with Mockito 3.7.7 and JUnit 4.13.1 in all cases):

import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner

import static org.mockito.Mockito.verify

@RunWith(MockitoJUnitRunner)
class GroovyMockitoTest {
    static class Helper {
        void helper() { }
    }

    static class Service {
        private final Helper helper

        Service(Helper helper) {
            this.helper = helper
        }

        void service() {
            helper.helper()
        }
    }

    @Mock Helper helper
    @InjectMocks Service service

    @Test
    void testService() {
        service.service()
        verify(helper).helper()
    }
}

The actual error:

java.lang.NullPointerException
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:38)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
	at GroovyMockitoTest$Service.service(GroovyMockitoTest.groovy:24)
	at GroovyMockitoTest$Service$service.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
	at GroovyMockitoTest.testService(GroovyMockitoTest.groovy:33)
	[... junit ...]

I guess this is like #72, where getMetaClass() is not ignored and returns null.

I think the difference is that in Groovy 3.0, internal methods such as getMetaClass() are no longer marked synthetic: GROOVY-8495. Now they are @groovy.transform.Generated and @groovy.transform.Internal.

As far as I can tell, Mockito works with Groovy 2.4/2.5 only because ByteBuddy ignores synthetic methods. I see the existing ignoreAlso(isGroovyMethod()) but as far as I can tell, it has no effect with current versions of Groovy. (I assume it did in the past.)

I think that the fix is to ignore methods annotated with @groovy.transform.Internal. I don't know whether that should be done in Mockito or in ByteBuddy. Please let me know if I should report it somewhere else, or if you'd like me to ask the Groovy developers for their input.

Thank you for working on Mockito!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions