From 84774556217c23472e54ff9ffe32bc041a40426d Mon Sep 17 00:00:00 2001 From: Ryan Tandy Date: Mon, 15 Feb 2021 11:23:25 -0800 Subject: [PATCH] Fixes #2204: Ignore Groovy methods annotated with Internal (#2207) Starting from Groovy 3.0, compiler-generated methods such as `getMetaClass()` are no longer marked synthetic, therefore ByteBuddy stopped automatically ignoring them. Instead they are now annotated with `@groovy.transform.Internal`. Update `isGroovyMethod()` to also check this new annotation. --- gradle/dependencies.gradle | 2 + settings.gradle.kts | 1 + .../bytebuddy/SubclassBytecodeGenerator.java | 3 +- subprojects/groovyTest/groovyTest.gradle | 11 +++++ .../mockito/groovy/GroovyMockitoTest.groovy | 46 +++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 subprojects/groovyTest/groovyTest.gradle create mode 100644 subprojects/groovyTest/src/test/groovy/org/mockito/groovy/GroovyMockitoTest.groovy diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 931a4e74f2..3e69d3402e 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -35,6 +35,8 @@ libraries.osgi = 'org.osgi:osgi.core:8.0.0' libraries.equinox = 'org.eclipse.platform:org.eclipse.osgi:3.16.100' libraries.bndGradle = 'biz.aQute.bnd:biz.aQute.bnd.gradle:5.2.0' +libraries.groovy = 'org.codehaus.groovy:groovy:3.0.7' + def kotlinVersion = '1.4.30' libraries.kotlin = [ version: kotlinVersion, diff --git a/settings.gradle.kts b/settings.gradle.kts index faef1b8d6e..530d545091 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,7 @@ plugins { include("deprecatedPluginsTest", "inline", "extTest", + "groovyTest", "kotlinTest", "kotlinReleaseCoroutinesTest", "android", diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java index cd2b177640..5937824f63 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java @@ -226,7 +226,8 @@ private Collection> getAllTypes(Class type) { } private static ElementMatcher isGroovyMethod() { - return isDeclaredBy(named("groovy.lang.GroovyObjectSupport")); + return isDeclaredBy(named("groovy.lang.GroovyObjectSupport")) + .or(isAnnotatedWith(named("groovy.transform.Internal"))); } private boolean isComingFromJDK(Class type) { diff --git a/subprojects/groovyTest/groovyTest.gradle b/subprojects/groovyTest/groovyTest.gradle new file mode 100644 index 0000000000..eceb4cdf79 --- /dev/null +++ b/subprojects/groovyTest/groovyTest.gradle @@ -0,0 +1,11 @@ +apply plugin: 'groovy' + +description = "Integration test for using Mockito from Groovy." + +apply from: "$rootDir/gradle/dependencies.gradle" + +dependencies { + testCompile project(":") + testCompile libraries.groovy + testCompile libraries.junit4 +} diff --git a/subprojects/groovyTest/src/test/groovy/org/mockito/groovy/GroovyMockitoTest.groovy b/subprojects/groovyTest/src/test/groovy/org/mockito/groovy/GroovyMockitoTest.groovy new file mode 100644 index 0000000000..b472aaabcc --- /dev/null +++ b/subprojects/groovyTest/src/test/groovy/org/mockito/groovy/GroovyMockitoTest.groovy @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Mockito contributors + * This program is made available under the terms of the MIT License. + */ +package org.mockito.groovy + +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 { + + @Mock Helper helper + @InjectMocks ClassUnderTest classUnderTest + + /** + * Test that the Groovy class under test can call methods on a mocked Groovy + * helper class. + */ + @Test + void testCallGroovyFromGroovy() { + classUnderTest.methodUnderTest() + verify(helper).helperMethod() + } + + static class ClassUnderTest { + private final Helper helper + + ClassUnderTest(Helper helper) { + this.helper = helper + } + + void methodUnderTest() { + helper.helperMethod() + } + } + + static class Helper { + void helperMethod() { } + } +}