From a6bd461e3b66369a18e8e39cde61d37bd88428de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 12 Mar 2024 08:26:23 +0100 Subject: [PATCH] Adapt to Mockito support in the Test Context Framework This commit updates MockitoTestExecutionListener to not handle mocks as this is already done in the listener provided by the core framework, and registration can only happen once. Integration tests have been left as-is to validate that the presence of both listeners don't have an unwanted side effect. --- .../mockito/MockitoTestExecutionListener.java | 68 +------------------ .../MockitoTestExecutionListenerTests.java | 10 +-- 2 files changed, 2 insertions(+), 76 deletions(-) diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java index be4561d45a53..0da250af7e76 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java @@ -16,27 +16,18 @@ package org.springframework.boot.test.mock.mockito; -import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.util.LinkedHashSet; -import java.util.Set; import java.util.function.BiConsumer; -import org.mockito.Captor; -import org.mockito.MockitoAnnotations; - import org.springframework.test.context.TestContext; import org.springframework.test.context.TestExecutionListener; import org.springframework.test.context.support.AbstractTestExecutionListener; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; import org.springframework.util.ReflectionUtils; -import org.springframework.util.ReflectionUtils.FieldCallback; /** * {@link TestExecutionListener} to enable {@link MockBean @MockBean} and - * {@link SpyBean @SpyBean} support. Also triggers - * {@link MockitoAnnotations#openMocks(Object)} when any Mockito annotations used, - * primarily to allow {@link Captor @Captor} annotations. + * {@link SpyBean @SpyBean} support. *

* To use the automatic reset support of {@code @MockBean} and {@code @SpyBean}, configure * {@link ResetMocksTestExecutionListener} as well. @@ -49,8 +40,6 @@ */ public class MockitoTestExecutionListener extends AbstractTestExecutionListener { - private static final String MOCKS_ATTRIBUTE_NAME = MockitoTestExecutionListener.class.getName() + ".mocks"; - @Override public final int getOrder() { return 1950; @@ -58,8 +47,6 @@ public final int getOrder() { @Override public void prepareTestInstance(TestContext testContext) throws Exception { - closeMocks(testContext); - initMocks(testContext); injectFields(testContext); } @@ -67,41 +54,10 @@ public void prepareTestInstance(TestContext testContext) throws Exception { public void beforeTestMethod(TestContext testContext) throws Exception { if (Boolean.TRUE.equals( testContext.getAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE))) { - closeMocks(testContext); - initMocks(testContext); reinjectFields(testContext); } } - @Override - public void afterTestMethod(TestContext testContext) throws Exception { - closeMocks(testContext); - } - - @Override - public void afterTestClass(TestContext testContext) throws Exception { - closeMocks(testContext); - } - - private void initMocks(TestContext testContext) { - if (hasMockitoAnnotations(testContext)) { - testContext.setAttribute(MOCKS_ATTRIBUTE_NAME, MockitoAnnotations.openMocks(testContext.getTestInstance())); - } - } - - private void closeMocks(TestContext testContext) throws Exception { - Object mocks = testContext.getAttribute(MOCKS_ATTRIBUTE_NAME); - if (mocks instanceof AutoCloseable closeable) { - closeable.close(); - } - } - - private boolean hasMockitoAnnotations(TestContext testContext) { - MockitoAnnotationCollection collector = new MockitoAnnotationCollection(); - ReflectionUtils.doWithFields(testContext.getTestClass(), collector); - return collector.hasAnnotations(); - } - private void injectFields(TestContext testContext) { postProcessFields(testContext, (mockitoField, postProcessor) -> postProcessor.inject(mockitoField.field, mockitoField.target, mockitoField.definition)); @@ -130,28 +86,6 @@ private void postProcessFields(TestContext testContext, BiConsumer annotations = new LinkedHashSet<>(); - - @Override - public void doWith(Field field) throws IllegalArgumentException { - for (Annotation annotation : field.getDeclaredAnnotations()) { - if (annotation.annotationType().getName().startsWith("org.mockito")) { - this.annotations.add(annotation); - } - } - } - - boolean hasAnnotations() { - return !this.annotations.isEmpty(); - } - - } - private static final class MockitoField { private final Field field; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java index 3ce7d272a2eb..74dacbdcf1b2 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-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. @@ -53,14 +53,6 @@ class MockitoTestExecutionListenerTests { @Mock private MockitoPostProcessor postProcessor; - @Test - void prepareTestInstanceShouldInitMockitoAnnotations() throws Exception { - WithMockitoAnnotations instance = new WithMockitoAnnotations(); - this.listener.prepareTestInstance(mockTestContext(instance)); - assertThat(instance.mock).isNotNull(); - assertThat(instance.captor).isNotNull(); - } - @Test void prepareTestInstanceShouldInjectMockBean() throws Exception { given(this.applicationContext.getBean(MockitoPostProcessor.class)).willReturn(this.postProcessor);