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

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

Comments

@rtandy
Copy link
Contributor

rtandy commented Feb 14, 2021

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!

@TimvdLippe
Copy link
Contributor

I think the cleanest solution would be to update isGroovyMethod to ignore the new annotations. Do you mind sending a PR?

facebook-github-bot pushed a commit to facebook/flipper that referenced this issue Mar 23, 2021
Summary:
Bumps [mockito-core](https://github.com/mockito/mockito) from 2.26.0 to 3.8.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/mockito/mockito/releases">mockito-core's releases</a>.</em></p>
<blockquote>
<h2>v3.8.0</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.8.0</h4>
<ul>
<li>2021-02-22 - <a href="https://github.com/mockito/mockito/compare/v3.7.18...v3.8.0">1 commit(s)</a> by Tim van der Lippe</li>
<li>Publish new minor version to Maven central [(<a href="https://github.com/mockito/mockito/issues/2213">#2213</a>)](<a href="https://github.com/mockito/mockito/pull/2213">mockito/mockito#2213</a>)</li>
</ul>
<h2>v3.7.18</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.18</h4>
<ul>
<li>2021-02-15 - <a href="https://github.com/mockito/mockito/compare/v3.7.17...v3.7.18">1 commit(s)</a> by Ryan Tandy</li>
<li>Fixes <a href="https://github.com/mockito/mockito/issues/2204">#2204</a>: Ignore Groovy methods annotated with Internal [(<a href="https://github.com/mockito/mockito/issues/2207">#2207</a>)](<a href="https://github.com/mockito/mockito/pull/2207">mockito/mockito#2207</a>)</li>
<li>Groovy 3.0 internal methods are not ignored as they should be [(<a href="https://github.com/mockito/mockito/issues/2204">#2204</a>)](<a href="https://github.com/mockito/mockito/issues/2204">mockito/mockito#2204</a>)</li>
</ul>
<h2>v3.7.17</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.17</h4>
<ul>
<li>2021-02-15 - <a href="https://github.com/mockito/mockito/compare/v3.7.16...v3.7.17">1 commit(s)</a> by dependabot[bot]</li>
<li>Bump junit from 4.13.1 to 4.13.2 [(<a href="https://github.com/mockito/mockito/issues/2205">#2205</a>)](<a href="https://github.com/mockito/mockito/pull/2205">mockito/mockito#2205</a>)</li>
</ul>
<h2>v3.7.16</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.16</h4>
<ul>
<li>2021-02-11 - <a href="https://github.com/mockito/mockito/compare/v3.7.15...v3.7.16">1 commit(s)</a> by Rafael Winterhalter</li>
<li>Add API for clearing mocks. [(<a href="https://github.com/mockito/mockito/issues/2194">#2194</a>)](<a href="https://github.com/mockito/mockito/pull/2194">mockito/mockito#2194</a>)</li>
</ul>
<h2>v3.7.15</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.15</h4>
<ul>
<li>2021-02-05 - <a href="https://github.com/mockito/mockito/compare/v3.7.13...v3.7.15">2 commit(s)</a> by dependabot[bot]</li>
<li>Bump versions.junitJupiter from 5.7.0 to 5.7.1 [(<a href="https://github.com/mockito/mockito/issues/2199">#2199</a>)](<a href="https://github.com/mockito/mockito/pull/2199">mockito/mockito#2199</a>)</li>
<li>Bump junit-platform-launcher from 1.7.0 to 1.7.1 [(<a href="https://github.com/mockito/mockito/issues/2198">#2198</a>)](<a href="https://github.com/mockito/mockito/pull/2198">mockito/mockito#2198</a>)</li>
</ul>
<h2>v3.7.14</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.14</h4>
<ul>
<li>2021-02-05 - <a href="https://github.com/mockito/mockito/compare/v3.7.13...v3.7.14">1 commit(s)</a> by dependabot[bot]</li>
<li>Bump versions.junitJupiter from 5.7.0 to 5.7.1 [(<a href="https://github.com/mockito/mockito/issues/2199">#2199</a>)](<a href="https://github.com/mockito/mockito/pull/2199">mockito/mockito#2199</a>)</li>
</ul>
<h2>v3.7.13</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog generated by <a href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h4>3.7.13</h4>
<ul>
<li>2021-02-04 - <a href="https://github.com/mockito/mockito/compare/v3.7.11...v3.7.13">2 commit(s)</a> by dependabot[bot]</li>
<li>Bump kotlin-stdlib from 1.4.21-2 to 1.4.30 [(<a href="https://github.com/mockito/mockito/issues/2196">#2196</a>)](<a href="https://github.com/mockito/mockito/pull/2196">mockito/mockito#2196</a>)</li>
</ul>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/mockito/mockito/commit/900552416c42a494c564a314a34072afc3cc0502"><code>9005524</code></a> Publish new minor version to Maven central (<a href="https://github.com/mockito/mockito/issues/2213">#2213</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/84774556217c23472e54ff9ffe32bc041a40426d"><code>8477455</code></a> Fixes <a href="https://github.com/mockito/mockito/issues/2204">#2204</a>: Ignore Groovy methods annotated with Internal (<a href="https://github.com/mockito/mockito/issues/2207">#2207</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/c2488e0a2a0682bd396e9260b0863b89ee554437"><code>c2488e0</code></a> Bump junit from 4.13.1 to 4.13.2 (<a href="https://github.com/mockito/mockito/issues/2205">#2205</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/e88fe26110afd6641c464cb0e87bd898b41bf457"><code>e88fe26</code></a> Add API for clearing mocks. (<a href="https://github.com/mockito/mockito/issues/2194">#2194</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/3bffcd0e8f9e1e0fe5678a99e7e9f37426e10635"><code>3bffcd0</code></a> Bump junit-platform-launcher from 1.7.0 to 1.7.1 (<a href="https://github.com/mockito/mockito/issues/2198">#2198</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/632a0c829a9d9fe6f55d89e4f4593a3d76a6d4cc"><code>632a0c8</code></a> Bump versions.junitJupiter from 5.7.0 to 5.7.1 (<a href="https://github.com/mockito/mockito/issues/2199">#2199</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/43facffb6861bb73c41560c39ba5aaa592a452fc"><code>43facff</code></a> Bump versions.bytebuddy from 1.10.19 to 1.10.20 (<a href="https://github.com/mockito/mockito/issues/2195">#2195</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/7745992ae91751df134b7ea09e1ef1ca4d39242a"><code>7745992</code></a> Bump kotlin-stdlib from 1.4.21-2 to 1.4.30 (<a href="https://github.com/mockito/mockito/issues/2196">#2196</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/780cfc18b06e82cf6592fc5f250b2e52f6f6a9e6"><code>780cfc1</code></a> Bump shipkit-changelog from 1.1.1 to 1.1.4 (<a href="https://github.com/mockito/mockito/issues/2190">#2190</a>)</li>
<li><a href="https://github.com/mockito/mockito/commit/8a19d46c19fc00c56bfcaa01274bb2195d9ac6fe"><code>8a19d46</code></a> Fixes <a href="https://github.com/mockito/mockito/issues/2154">#2154</a> : instrument java.lang.Object to fix toString invocations on inli...</li>
<li>Additional commits viewable in <a href="https://github.com/mockito/mockito/compare/v2.26.0...v3.8.0">compare view</a></li>
</ul>
</details>
<br />

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.mockito:mockito-core&package-manager=gradle&previous-version=2.26.0&new-version=3.8.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

 ---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `dependabot rebase` will rebase this PR
- `dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `dependabot merge` will merge this PR after your CI passes on it
- `dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `dependabot cancel merge` will cancel a previously requested merge and block automerging
- `dependabot reopen` will reopen this PR if it is closed
- `dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

</details>

Pull Request resolved: #2059

Reviewed By: passy

Differential Revision: D27230345

Pulled By: priteshrnandgaonkar

fbshipit-source-id: 2ecfcfa9a155ff2b14c41e913200e6056e9f60d1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment