Skip to content

MockitoWhenOnStaticToMockStatic creates nested MockedStatic blocks for the same class #1004

@protocol7

Description

@protocol7

What version of OpenRewrite are you using?

  • rewrite-testing-frameworks: 3.35.2
  • rewrite-core: 8.81.7
  • rewrite-java: 8.81.7

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

When a single scope contains multiple Mockito.when(StaticClass.staticMethod()) stubbings for the same static class, the recipe wraps each stubbing in its own try (MockedStatic) block instead of sharing one.

import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

class ExampleTest {
  @Test
  void test() {
    when(SomeStaticClass.methodA()).thenReturn("a");
    when(SomeStaticClass.methodB()).thenReturn("b");
  }
}

class SomeStaticClass {
  static String methodA() {
    return null;
  }

  static String methodB() {
    return null;
  }
}

Run org.openrewrite.java.testing.mockito.MockitoWhenOnStaticToMockStatic.

What did you expect to see?

All stubbings for the same class combined into a single try-with-resources block:

import static org.mockito.Mockito.mockStatic;

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

class ExampleTest {
  @Test
  void test() {
    try (MockedStatic<SomeStaticClass> mocked = mockStatic(SomeStaticClass.class)) {
      mocked.when(SomeStaticClass::methodA).thenReturn("a");
      mocked.when(SomeStaticClass::methodB).thenReturn("b");
    }
  }
}

What did you see instead?

Each stubbing is wrapped in its own nested MockedStatic block for the same class:

import static org.mockito.Mockito.mockStatic;

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

class ExampleTest {
  @Test
  void test() {
    try (MockedStatic<SomeStaticClass> mockedA = mockStatic(SomeStaticClass.class)) {
      mockedA.when(SomeStaticClass::methodA).thenReturn("a");
      try (MockedStatic<SomeStaticClass> mockedB = mockStatic(SomeStaticClass.class)) {
        mockedB.when(SomeStaticClass::methodB).thenReturn("b");
      }
    }
  }
}

At runtime Mockito 5 rejects the nested registration:

org.mockito.exceptions.base.MockitoException:
For SomeStaticClass, static mocking is already registered in the current thread

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions