Skip to content

MockitoExtension gets added even when not necessary #875

@DidierLoiseau

Description

@DidierLoiseau

What version of OpenRewrite are you using?

I am using

  • OpenRewrite v8.16.1
  • Maven plugin v6.25.0
  • rewrite-recipe-bom 3.20.0

How are you running OpenRewrite?

I am using the Maven plugin, and my project is a single module project.

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

Consider these classes:

@ExtendWith(MockitoExtension.class)
abstract class BaseTest {
}
class ChildTest extends BaseTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}
class ExplicitInitTest {
	@Mock
	Object underTest;

	@BeforeEach
	void setup() {
		MockitoAnnotations.openMocks(this);
	}

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}

(the next one only with Spring Boot < 4.0, I think)

@ExtendWith(SpringExtension.class)
class SpringExtensionTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(MockitoExtension.class)
@interface MyMockitoAnnotation {
}
@MyMockitoAnnotation
class CustomAnnotationTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}

These tests pass without an explicit @ExtendWith(MockitoExtension.class) on the test class itself.

What did you expect to see?

OpenRewrite should not alter these classes when running AddMockitoExtensionIfAnnotationsUsed, nor Java or Spring Boot upgrades.

What did you see instead?

The test classes all see @ExtendWith(MockitoExtension.class) being added:

@ExtendWith(MockitoExtension.class)
public class ChildTest extends BaseTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}
@ExtendWith(MockitoExtension.class)
public class ExplicitInitTest {
	@Mock
	Object underTest;

	@BeforeEach
	void setup() {
		MockitoAnnotations.openMocks(this);
	}

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}
@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
public class SpringExtensionTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}
@ExtendWith(MockitoExtension.class)
@MyMockitoAnnotation
class CustomAnnotationTest {
	@Mock
	Object underTest;

	@Test
	void myTest() {
		assertNotNull(underTest);
	}
}

The extension shouldn’t be added when one of the following is true:

  • a parent class already has it
  • there is an explicit call to MockitoAnnotations.initMocks() or MockitoAnnotations.openMocks() (it could be in a parent class too!)
  • using the SpringExtension in SB < 3.4, maybe? (in 3.4 this usage appears to have been tacitly deprecated, and removed in SB 4, hence Add @ExtendWith(MockitoExtension.class) Test using Mockito Annotations #848 )
  • the test class (or one of its parents) is meta-annotated with one of these extensions
  • maybe other conditions?

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

[WARNING] Changes have been made to src\test\java\…\ChildTest.java by:
[WARNING]         org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5
[WARNING]             org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_4
[WARNING]                 org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3
[WARNING]                     org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2
[WARNING]                         org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_1
[WARNING]                             org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0
[WARNING]                                 org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7
[WARNING]                                     org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_6
[WARNING]                                         org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_5
[WARNING]                                             org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_4
[WARNING]                                                 org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration
[WARNING]                                                     org.openrewrite.java.testing.junit5.JUnit4to5Migration
[WARNING]                                                         org.openrewrite.java.testing.junit5.UseMockitoExtension
[WARNING]                                                             org.openrewrite.java.testing.mockito.Mockito1to4Migration
[WARNING]                                                                 org.openrewrite.java.testing.mockito.Mockito1to3Migration
[WARNING]                                                                     org.openrewrite.java.testing.mockito.CleanupMockitoImports
[WARNING]                                                                     org.openrewrite.java.testing.mockito.AddMockitoExtensionIfAnnotationsUsed

(log is similar for the other classes)

Are you interested in contributing a fix to OpenRewrite?

I’m not too sure how to implement all these negative cases, especially the ones related to parent classes.

Maybe for the time being, a temporary solution would be to edge on the safe side and only make the change when SpringExtension is used, and only during the Spring Boot 4 migration? This appears to have been the main target from #848 (by @MBoegers).

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions