openrewrite / openrewrite/rewrite-testing-frameworks

Mockito1to5Migration leaves anyListOf uncompilable when matchers are reached through `import static org.mockito.Mockito.*`

Open
#1,115 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
100
Forks
105
Avg merge
2h 25m
Merged PRs (30d)
9

Description

Versions

rewrite-maven-plugin 6.46.1, rewrite-testing-frameworks 3.44.0 (latest on Central, published
2026-08-12). The behaviour is also present on the default branch — see "Mechanism" below.

Summary

Mockito1to5Migration bumps the POM to mockito-core:5.x but does not rewrite
anyListOf(X.class) when it was reached via import static org.mockito.Mockito.*. Since
anyListOf no longer exists in Mockito 5, the project stops compiling.

Whether the rewrite happens depends on how the matcher was imported, not on what the code does.

Reproduction

pom.xml: junit:junit:4.11, org.mockito:mockito-all:1.9.5, source/target 8.

Two test classes that do exactly the same thing:

// ViaMockitoTest.java  — the common idiom
import static org.mockito.Mockito.*;

public class ViaMockitoTest {
    interface Service { void handle(List<String> items); }

    @Test
    public void reachedThroughMockitoStarImport() {
        Service s = mock(Service.class);
        s.handle(null);
        verify(s).handle(anyListOf(String.class));
    }
}
// ViaMatchersTest.java — same call, imported from Matchers
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
// ... identical body
mvn -U org.openrewrite.maven:rewrite-maven-plugin:6.46.1:run \
  -Drewrite.activeRecipes=org.openrewrite.java.testing.mockito.Mockito1to5Migration \
  -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-testing-frameworks:3.44.0

Result

ViaMatchersTest — migrated correctly:

-import static org.mockito.Matchers.anyListOf;
+import static org.mockito.ArgumentMatchers.anyList;
-        verify(s).handle(anyListOf(String.class));
+        verify(s).handle(anyList());

ViaMockitoTestno change at all. But the POM was upgraded:

org.mockito:mockito-core:5.23.0

so the build now fails:

ViaMockitoTest.java:[15,26] cannot find symbol

anyListOf is absent from both ArgumentMatchers and Mockito in Mockito 5.

Mechanism

In Mockito 1.x, org.mockito.Mockito extends org.mockito.Matchers, so anyListOf is inherited
and import static org.mockito.Mockito.* resolves it. OpenRewrite then attributes the invocation's
declaring type to org.mockito.Mockito.

The recipe chain handles matchers in two steps: ChangeType org.mockito.Matchers ->
org.mockito.ArgumentMatchers, and then renames keyed on the new type —

- org.openrewrite.java.ChangeMethodName:
    methodPattern: org.mockito.ArgumentMatchers anyListOf(java.lang.Class)
    newMethodName: anyList
- org.openrewrite.java.DeleteMethodArgument:
    methodPattern: org.mockito.ArgumentMatchers anyList(java.lang.Class)
    argumentIndex: 0

Neither step touches a call attributed to org.mockito.Mockito, so the inherited path is missed
entirely.

Counting declaring types in mockito.yml, the matcher rewrites are keyed on
org.mockito.ArgumentMatchers 13 times in 3.44.0 (15 on the default branch), and on
org.mockito.Mockito exactly once — for anyObject(). So the inherited path is already known
to exist; it is just covered for one method out of the family.

Suggested fix

Duplicate the anyXOf family keyed on org.mockito.Mockito as well, the way anyObject()
already is. In a real 2016 codebase I hit this at 21 call sites in 2 files, every one of which
would have been left broken.

Relationship to existing issues

  • #282 (2022) fixed the pattern by keying on org.mockito.Matchers; the keying has since moved
    to ArgumentMatchers. Both are the non-inherited path.
  • #1098 / #1100 (merged 2026-08-20, after 3.44.0 was published) add
    anyCollectionOf/anyIterableOf, still keyed on ArgumentMatchers.

None of them covers a call whose declaring type resolves to org.mockito.Mockito, which is why
this is still reproducible on the latest release.

Note

This was found by an agent migrating a real project, which diagnosed it with a two-variant probe
recipe — the Matchers-keyed pattern matched nothing, the Mockito-keyed pattern matched both
files — and then added the missing rewrites locally to get its build green. I reproduced it
independently from scratch before filing.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mockito.yml, focusing on the Mockito1to5Migration matcher entries and the existing org.mockito.Mockito handling for anyObject(). Run the supplied Maven reproduction with both import variants, then verify that anyListOf(String.class) reached through the Mockito star import is rewritten and the migrated project compiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.