Remove support for Mockito annotations and MockitoSession
This change remove the support for Mockito annotations, `MockitoSession`
and opening/closing of mocks that was inherited from Boot's `@MockBean`
support, as well as the switch to `MockitoSession` made in 1c893e6.
Attempting to take responsability for things Mockito's own JUnit
Jupiter extension does better is not ideal, and we found it leads to
several corner cases which make `SpringExtension` and `MockitoExtension`
incompatible in the current approach.
Instead, this change refocuses our Mockito bean overriding support
exclusively on aspects specific to the Framework. `MockitoExtension`
will thus be usable in conjunction with `SpringExtension` if one needs
to use `@Captor`/`@InitMocks`/`@Mock`/`@Spy` or other Mockito utilities.
See gh-33318
Closes gh-33692
This commit is contained in:
@@ -66,8 +66,6 @@ package org.springframework.test.context;
|
||||
* DirtiesContextBeforeModesTestExecutionListener}</li>
|
||||
* <li>{@link org.springframework.test.context.event.ApplicationEventsTestExecutionListener
|
||||
* ApplicationEventsTestExecutionListener}</li>
|
||||
* <li>{@link org.springframework.test.context.bean.override.mockito.MockitoTestExecutionListener
|
||||
* MockitoTestExecutionListener}</li>
|
||||
* <li>{@link org.springframework.test.context.support.DependencyInjectionTestExecutionListener
|
||||
* DependencyInjectionTestExecutionListener}</li>
|
||||
* <li>{@link org.springframework.test.context.observation.MicrometerObservationRegistryTestExecutionListener
|
||||
|
||||
@@ -82,7 +82,6 @@ public @interface TestExecutionListeners {
|
||||
* @see org.springframework.test.context.web.ServletTestExecutionListener
|
||||
* @see org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener
|
||||
* @see org.springframework.test.context.event.ApplicationEventsTestExecutionListener
|
||||
* @see org.springframework.test.context.bean.override.mockito.MockitoTestExecutionListener
|
||||
* @see org.springframework.test.context.support.DependencyInjectionTestExecutionListener
|
||||
* @see org.springframework.test.context.support.DirtiesContextTestExecutionListener
|
||||
* @see org.springframework.test.context.support.CommonCachesTestExecutionListener
|
||||
|
||||
@@ -42,19 +42,16 @@ abstract class AbstractMockitoTestExecutionListener extends AbstractTestExecutio
|
||||
|
||||
private static final String SPRING_MOCKITO_PACKAGE = "org.springframework.test.context.bean.override.mockito";
|
||||
|
||||
private static final String ORG_MOCKITO_PACKAGE = "org.mockito";
|
||||
|
||||
private static final Predicate<MergedAnnotation<?>> isMockitoAnnotation = mergedAnnotation -> {
|
||||
String packageName = mergedAnnotation.getType().getPackageName();
|
||||
return (packageName.startsWith(SPRING_MOCKITO_PACKAGE) ||
|
||||
packageName.startsWith(ORG_MOCKITO_PACKAGE));
|
||||
return packageName.startsWith(SPRING_MOCKITO_PACKAGE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if the test class for the supplied {@linkplain TestContext
|
||||
* test context} uses {@code org.mockito} annotations or any of the annotations
|
||||
* in this package (such as {@link MockitoBeanSettings @MockitoBeanSettings}).
|
||||
* test context} uses any of the annotations in this package (such as
|
||||
* {@link MockitoBean @MockitoBean}).
|
||||
*/
|
||||
static boolean hasMockitoAnnotations(TestContext testContext) {
|
||||
return hasMockitoAnnotations(testContext.getTestClass());
|
||||
|
||||
@@ -1,47 +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.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
/**
|
||||
* Configure a test class that uses {@link MockitoBean @MockitoBean} or
|
||||
* {@link MockitoSpyBean @MockitoSpyBean} to set up Mockito with an explicit
|
||||
* stubbing strictness mode.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @since 6.2
|
||||
* @see MockitoTestExecutionListener
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface MockitoBeanSettings {
|
||||
|
||||
/**
|
||||
* The stubbing strictness mode to apply for all Mockito mocks in the annotated
|
||||
* test class.
|
||||
*/
|
||||
Strictness value();
|
||||
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import org.springframework.test.context.TestContext;
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
* @see MockitoTestExecutionListener
|
||||
* @see MockitoBean @MockitoBean
|
||||
* @see MockitoSpyBean @MockitoSpyBean
|
||||
*/
|
||||
|
||||
@@ -1,102 +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 org.mockito.Mockito;
|
||||
import org.mockito.MockitoSession;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestContextAnnotationUtils;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
|
||||
/**
|
||||
* {@code TestExecutionListener} that manages a {@link MockitoSession} for each
|
||||
* test class that uses {@link MockitoBean @MockitoBean},
|
||||
* {@link MockitoSpyBean @MockitoSpyBean},
|
||||
* {@link MockitoBeanSettings @MockitoBeanSettings}, or any annotations from the
|
||||
* {@code org.mockito} package.
|
||||
*
|
||||
* <p>The {@link MockitoSession#setStrictness(Strictness) strictness} of the
|
||||
* session defaults to {@link Strictness#STRICT_STUBS}. Use
|
||||
* {@code @MockitoBeanSettings} to specify a different strictness.
|
||||
*
|
||||
* <p>Dependency injection for {@code @MockitoBean} and {@code @MockitoSpyBean}
|
||||
* fields is handled by the
|
||||
* {@link org.springframework.test.context.bean.override.BeanOverrideTestExecutionListener
|
||||
* BeanOverrideTestExecutionListener}, and automatic reset support for
|
||||
* {@code @MockitoBean} and {@code @MockitoSpyBean} is handled by the
|
||||
* {@link MockitoResetTestExecutionListener}.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
* @see MockitoResetTestExecutionListener
|
||||
* @see MockitoBean @MockitoBean
|
||||
* @see MockitoSpyBean @MockitoSpyBean
|
||||
*/
|
||||
public class MockitoTestExecutionListener extends AbstractMockitoTestExecutionListener {
|
||||
|
||||
private static final String MOCKITO_SESSION_ATTRIBUTE_NAME =
|
||||
MockitoTestExecutionListener.class.getName() + ".mockitoSession";
|
||||
|
||||
|
||||
/**
|
||||
* Executes before {@link DependencyInjectionTestExecutionListener}.
|
||||
*/
|
||||
@Override
|
||||
public final int getOrder() {
|
||||
return 1950;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) {
|
||||
if (mockitoPresent && hasMockitoAnnotations(testContext)) {
|
||||
initMocks(testContext);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestMethod(TestContext testContext) {
|
||||
if (mockitoPresent && hasMockitoAnnotations(testContext)) {
|
||||
closeMocks(testContext);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initMocks(TestContext testContext) {
|
||||
Class<?> testClass = testContext.getTestClass();
|
||||
Object testInstance = testContext.getTestInstance();
|
||||
MockitoBeanSettings annotation =
|
||||
TestContextAnnotationUtils.findMergedAnnotation(testClass, MockitoBeanSettings.class);
|
||||
Strictness strictness = (annotation != null ? annotation.value() : Strictness.STRICT_STUBS);
|
||||
testContext.setAttribute(MOCKITO_SESSION_ATTRIBUTE_NAME, initMockitoSession(testInstance, strictness));
|
||||
}
|
||||
|
||||
private static MockitoSession initMockitoSession(Object testInstance, Strictness strictness) {
|
||||
return Mockito.mockitoSession()
|
||||
.initMocks(testInstance)
|
||||
.strictness(strictness)
|
||||
.startMocking();
|
||||
}
|
||||
|
||||
private static void closeMocks(TestContext testContext) {
|
||||
if (testContext.getAttribute(MOCKITO_SESSION_ATTRIBUTE_NAME) instanceof MockitoSession session) {
|
||||
session.finishMocking();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user