Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Issue when MockedStatic field is defined with an inline Mockito.mockStatic initialiser

Aperta
#1,127 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
74/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
java
Ambito
testing-qa

Direzione di ricerca

Inizia da org.openrewrite.java.testing.mockito.CloseUnclosedStaticMocks, in particolare dal percorso visitBlock() e dal relativo controllo dei metodi del ciclo di vita, usando il riproduttore inline con il campo MockedStatic riportato nell’issue. Aggiungi una copertura di regressione per questo caso nel corpo della classe e verifica che la recipe non generi più un’eccezione e preservi il campo quando la pulizia è già gestita, quindi esegui i test pertinenti di rewrite-testing-frameworks.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

What version of OpenRewrite are you using?

I am using

  • Maven plugin: org.openrewrite.maven:rewrite-maven-plugin v6.44.0
  • org.openrewrite.recipe:rewrite-spring v6.35.0
  • org.openrewrite.recipe:rewrite-testing-frameworks v3.42.0 (pulled in transitively by rewrite-spring)

The bug lives in org.openrewrite.java.testing.mockito.CloseUnclosedStaticMocks, in rewrite-testing-frameworks. It is reached transitively via:

org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 → spring-boot-31.yml's org.openrewrite.java.testing.mockito.Mockito4to5Only → org.openrewrite.java.testing.mockito.Mockito1to4Migration → org.openrewrite.java.testing.mockito.CloseUnclosedStaticMocks (last recipe in Mockito1to4Migration's recipeList, per mockito.yml).

How are you running OpenRewrite?

I am using the Maven plugin (rewrite-maven-plugin:run), on a single-module project, running a declarative recipe chain that includes org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5.

<plugin>
  <groupId>org.openrewrite.maven</groupId>
  <artifactId>rewrite-maven-plugin</artifactId>
  <version>6.44.0</version>
  <configuration>
    <activeRecipes>
      <recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5</recipe>
    </activeRecipes>
  </configuration>
</plugin>

What is the smallest, simplest way to reproduce the problem?

package com.example;

import org.mockito.MockedStatic;
import org.mockito.Mockito;

class MyTest {
    private static final MockedStatic<CryptoUtil> MOCKED_CRYPTO_UTILS = Mockito.mockStatic(CryptoUtil.class);
}

Any test class that declares a MockedStatic field with an inline Mockito.mockStatic(...) initializer directly in the class body (as opposed to assigning it in a @BeforeAll/@BeforeEach lifecycle method) triggers the crash:

Root cause (confirmed by reading CloseUnclosedStaticMocks's source from rewrite-testing-frameworks-3.42.0-sources.jar): its visitBlock() override fires on any J.Block, but a class body is also represented as a J.Block in the LST, just like a method body. The recipe guards against lifecycle-method blocks (insideLifecycleMethod()), but not against the class-body block itself. So it mistakes this field declaration for an "unclosed local variable" inside a block, and attempts to wrap it in a try (#{any()}) {} template — which isn't valid for a field declaration (its modifiers, e.g. private static final, aren't compatible with a try-with-resources resource declaration). The resulting JavaTemplate.apply() call generates 2 statements instead of the expected 1 replacement statement, and throws.

Note that the recipe's separate assignment-based path (visitAssignment / DeclareMockVarAndClose, used when mockStatic() appears as VAR = Mockito.mockStatic(X.class); rather than as an inline field initializer) works correctly, including correctly recognizing a pre-existing manual .close() call as already handling cleanup. The bug is specific to the inline-field-initializer form.

What did you expect to see?

Since the field's MockedStatic is already closed manually elsewhere (e.g. in a matching @AfterAll), I'd expect the recipe to make no change, e.g.:

package com.example;

import org.mockito.MockedStatic;
import org.mockito.Mockito;

class MyTest {
    private static final MockedStatic<CryptoUtil> MOCKED_CRYPTO_UTILS = Mockito.mockStatic(CryptoUtil.class);

    @AfterAll
    static void afterAll() {
        MOCKED_CRYPTO_UTILS.close();
    }
}

What did you see instead?

At minimum, I'd expect the recipe to not crash the whole run — e.g. it could correctly detect the existing .close() call the way it already does for the assignment-based form, or leave inline-initialized class-body fields alone entirely if it can't safely rewrite them.

What is the full stack trace of any errors you encountered?

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:6.44.0:run (default-cli) on project AppFunctionalTests: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:6.44.0:run failed: Error while visiting app_name/AppFunctionalTests/filename.java: java.lang.IllegalArgumentException: Expected a template that would generate exactly one statement to replace one statement, but generated 2. Template:
[ERROR] try(__P__.<org.mockito.MockedStatic<Unknown>>/*__p0__*/p()) {}
[ERROR] Substitutions:
[ERROR] Substitutions(code=try(#{any()}) {}, genericTypes=[], parameters=[private static final MockedStatic<CryptoUtil> MOCKED_CRYPTO_UTILS = Mockito.mockStatic(CryptoUtil.class)], propertyPlaceholderHelper=org.openrewrite.internal.PropertyPlaceholderHelper@72eca5c5, typeVariables=[])
[ERROR] Statement:
[ERROR] private static final MockedStatic<CryptoUtil> MOCKED_CRYPTO_UTILS = Mockito.mockStatic(CryptoUtil.class)
	at org.openrewrite.java.JavaTemplate.apply(JavaTemplate.java:...)
	at org.openrewrite.java.testing.mockito.CloseUnclosedStaticMocks$CloseUnclosedStaticMocksVisitor.toTryWithResource(CloseUnclosedStaticMocks.java:...)
	at org.openrewrite.java.testing.mockito.CloseUnclosedStaticMocks$CloseUnclosedStaticMocksVisitor.visitBlock(CloseUnclosedStaticMocks.java:...)
	...

Are you interested in contributing a fix to OpenRewrite?

No.

Lingua principale
Java
Stelle
100
Fork
105
Merge medio
2g 15h
PR unite (30g)
13

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di openrewrite/rewrite-testing-frameworks

Tutte le issue di openrewrite/rewrite-testing-frameworks

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.