diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/AbstractMockitoTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/AbstractMockitoTestExecutionListener.java deleted file mode 100644 index 7ef700bfdc2..00000000000 --- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/AbstractMockitoTestExecutionListener.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.context.bean.override.mockito; - -import java.lang.reflect.Field; -import java.util.function.Predicate; - -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.TestContextAnnotationUtils; -import org.springframework.test.context.support.AbstractTestExecutionListener; -import org.springframework.util.ClassUtils; - -/** - * Abstract base class for {@code TestExecutionListener} implementations involving - * Mockito. - * - * @author Sam Brannen - * @author Simon Baslé - * @since 6.2 - */ -abstract class AbstractMockitoTestExecutionListener extends AbstractTestExecutionListener { - - static final boolean mockitoPresent = ClassUtils.isPresent("org.mockito.Mockito", - AbstractMockitoTestExecutionListener.class.getClassLoader()); - - private static final String SPRING_MOCKITO_PACKAGE = "org.springframework.test.context.bean.override.mockito"; - - private static final Predicate> isMockitoAnnotation = mergedAnnotation -> { - String packageName = mergedAnnotation.getType().getPackageName(); - return packageName.startsWith(SPRING_MOCKITO_PACKAGE); - }; - - - /** - * Determine if the test class for the supplied {@linkplain TestContext - * test context} uses any of the annotations in this package (such as - * {@link MockitoBean @MockitoBean}). - */ - static boolean hasMockitoAnnotations(TestContext testContext) { - return hasMockitoAnnotations(testContext.getTestClass()); - } - - /** - * Determine if Mockito annotations are declared on the supplied class, on an - * interface it implements, on a superclass, or on an enclosing class or - * whether a field in any such class is annotated with a Mockito annotation. - */ - private static boolean hasMockitoAnnotations(Class clazz) { - // Declared on the class? - if (MergedAnnotations.from(clazz, SearchStrategy.DIRECT).stream().anyMatch(isMockitoAnnotation)) { - return true; - } - - // Declared on a field? - for (Field field : clazz.getDeclaredFields()) { - if (MergedAnnotations.from(field, SearchStrategy.DIRECT).stream().anyMatch(isMockitoAnnotation)) { - return true; - } - } - - // Declared on an interface? - for (Class ifc : clazz.getInterfaces()) { - if (hasMockitoAnnotations(ifc)) { - return true; - } - } - - // Declared on a superclass? - Class superclass = clazz.getSuperclass(); - if (superclass != null & superclass != Object.class) { - if (hasMockitoAnnotations(superclass)) { - return true; - } - } - - // Declared on an enclosing class of an inner class? - if (TestContextAnnotationUtils.searchEnclosingClass(clazz)) { - if (hasMockitoAnnotations(clazz.getEnclosingClass())) { - return true; - } - } - - return false; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoResetTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoResetTestExecutionListener.java index 7f6b7225b9b..ad33068943d 100644 --- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoResetTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoResetTestExecutionListener.java @@ -16,9 +16,11 @@ package org.springframework.test.context.bean.override.mockito; +import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.function.Predicate; import org.mockito.Mockito; @@ -30,8 +32,13 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.Ordered; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.lang.Nullable; import org.springframework.test.context.TestContext; +import org.springframework.test.context.TestContextAnnotationUtils; +import org.springframework.test.context.support.AbstractTestExecutionListener; +import org.springframework.util.ClassUtils; /** * {@code TestExecutionListener} that resets any mock beans that have been marked @@ -43,7 +50,17 @@ import org.springframework.test.context.TestContext; * @see MockitoBean @MockitoBean * @see MockitoSpyBean @MockitoSpyBean */ -public class MockitoResetTestExecutionListener extends AbstractMockitoTestExecutionListener { +public class MockitoResetTestExecutionListener extends AbstractTestExecutionListener { + + static final boolean mockitoPresent = ClassUtils.isPresent("org.mockito.Mockito", + MockitoResetTestExecutionListener.class.getClassLoader()); + + private static final String SPRING_MOCKITO_PACKAGE = "org.springframework.test.context.bean.override.mockito"; + + private static final Predicate> isMockitoAnnotation = mergedAnnotation -> { + String packageName = mergedAnnotation.getType().getPackageName(); + return packageName.startsWith(SPRING_MOCKITO_PACKAGE); + }; /** * Executes before {@link org.springframework.test.context.bean.override.BeanOverrideTestExecutionListener}. @@ -67,6 +84,7 @@ public class MockitoResetTestExecutionListener extends AbstractMockitoTestExecut } } + private void resetMocks(ApplicationContext applicationContext, MockReset reset) { if (applicationContext instanceof ConfigurableApplicationContext configurableContext) { resetMocks(configurableContext, reset); @@ -119,4 +137,56 @@ public class MockitoResetTestExecutionListener extends AbstractMockitoTestExecut return true; } + /** + * Determine if the test class for the supplied {@linkplain TestContext + * test context} uses any of the annotations in this package (such as + * {@link MockitoBean @MockitoBean}). + */ + static boolean hasMockitoAnnotations(TestContext testContext) { + return hasMockitoAnnotations(testContext.getTestClass()); + } + + /** + * Determine if Mockito annotations are declared on the supplied class, on an + * interface it implements, on a superclass, or on an enclosing class or + * whether a field in any such class is annotated with a Mockito annotation. + */ + private static boolean hasMockitoAnnotations(Class clazz) { + // Declared on the class? + if (MergedAnnotations.from(clazz, MergedAnnotations.SearchStrategy.DIRECT).stream().anyMatch(isMockitoAnnotation)) { + return true; + } + + // Declared on a field? + for (Field field : clazz.getDeclaredFields()) { + if (MergedAnnotations.from(field, MergedAnnotations.SearchStrategy.DIRECT).stream().anyMatch(isMockitoAnnotation)) { + return true; + } + } + + // Declared on an interface? + for (Class ifc : clazz.getInterfaces()) { + if (hasMockitoAnnotations(ifc)) { + return true; + } + } + + // Declared on a superclass? + Class superclass = clazz.getSuperclass(); + if (superclass != null & superclass != Object.class) { + if (hasMockitoAnnotations(superclass)) { + return true; + } + } + + // Declared on an enclosing class of an inner class? + if (TestContextAnnotationUtils.searchEnclosingClass(clazz)) { + if (hasMockitoAnnotations(clazz.getEnclosingClass())) { + return true; + } + } + + return false; + } + }