Remove most deprecated APIs that were due for removal in 4.0

Support for rest controller, controler, and servlet endpoints has
been kept for now.

Closes gh-45600
This commit is contained in:
Andy Wilkinson 2025-06-10 20:11:08 +01:00
parent 76719a4e28
commit f90a5986e5
197 changed files with 208 additions and 10927 deletions

View File

@ -34,9 +34,9 @@ import org.springframework.core.env.Environment;
* endpoint is considered available if it is both enabled and exposed on the specified
* technologies.
* <p>
* Matches enablement according to the endpoints specific {@link Environment} property,
* falling back to {@code management.endpoints.enabled-by-default} or failing that
* {@link Endpoint#enableByDefault()}.
* Matches access according to the endpoint's specific {@link Environment} property,
* falling back to {@code management.endpoints.default-access} or failing that
* {@link Endpoint#defaultAccess()}.
* <p>
* Matches exposure according to any of the {@code management.endpoints.web.exposure.<id>}
* or {@code management.endpoints.jmx.exposure.<id>} specific properties or failing that

View File

@ -17,7 +17,6 @@
package org.springframework.boot.actuate.autoconfigure.endpoint.condition;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
@ -126,8 +125,7 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
private ConditionOutcome getAccessOutcome(Environment environment, MergedAnnotation<Endpoint> endpointAnnotation,
EndpointId endpointId, ConditionMessage.Builder message) {
Access defaultAccess = endpointAnnotation.getEnum("defaultAccess", Access.class);
boolean enableByDefault = endpointAnnotation.getBoolean("enableByDefault");
Access access = getAccess(environment, endpointId, (enableByDefault) ? defaultAccess : Access.NONE);
Access access = getAccess(environment, endpointId, defaultAccess);
return new ConditionOutcome(access != Access.NONE,
message.because("the configured access for endpoint '%s' is %s".formatted(endpointId, access)));
}
@ -153,17 +151,8 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
private Set<EndpointExposure> getExposures(MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation) {
EndpointExposure[] exposures = conditionAnnotation.getEnumArray("exposure", EndpointExposure.class);
return replaceCloudFoundryExposure(
(exposures.length == 0) ? EnumSet.allOf(EndpointExposure.class) : Arrays.asList(exposures));
}
@SuppressWarnings("removal")
private Set<EndpointExposure> replaceCloudFoundryExposure(Collection<EndpointExposure> exposures) {
Set<EndpointExposure> result = EnumSet.copyOf(exposures);
if (result.remove(EndpointExposure.CLOUD_FOUNDRY)) {
result.add(EndpointExposure.WEB);
}
return result;
return (exposures.length == 0) ? EnumSet.allOf(EndpointExposure.class)
: EnumSet.copyOf(Arrays.asList(exposures));
}
private Set<EndpointExposureOutcomeContributor> getExposureOutcomeContributors(ConditionContext context) {

View File

@ -32,16 +32,7 @@ public enum EndpointExposure {
/**
* Exposed over a web endpoint.
*/
WEB("health"),
/**
* Exposed on Cloud Foundry over `/cloudfoundryapplication`.
* @since 2.6.4
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of using
* {@link EndpointExposure#WEB}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
CLOUD_FOUNDRY("*");
WEB("health");
private final String[] defaultIncludes;

View File

@ -46,15 +46,6 @@ public class ManagementWebServerFactoryCustomizer<T extends ConfigurableWebServe
private final Class<? extends WebServerFactoryCustomizer<?>>[] customizerClasses;
@SafeVarargs
@SuppressWarnings("varargs")
@Deprecated(since = "3.5.0", forRemoval = true)
protected ManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory,
Class<? extends WebServerFactoryCustomizer<?>>... customizerClasses) {
this.beanFactory = beanFactory;
this.customizerClasses = customizerClasses;
}
/**
* Creates a new customizer that will retrieve beans using the given
* {@code beanFactory}.

View File

@ -273,21 +273,6 @@ class ConditionalOnAvailableEndpointTests {
.isInstanceOf(MutuallyExclusiveConfigurationPropertiesException.class));
}
@Test
void whenDisabledAndAccessibleByDefaultEndpointIsNotAvailable() {
this.contextRunner.withUserConfiguration(DisabledButAccessibleEndpointConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).doesNotHaveBean(DisabledButAccessibleEndpoint.class));
}
@Test
void whenDisabledAndAccessibleByDefaultEndpointCanBeAvailable() {
this.contextRunner.withUserConfiguration(DisabledButAccessibleEndpointConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoints.access.default=unrestricted")
.run((context) -> assertThat(context).hasSingleBean(DisabledButAccessibleEndpoint.class));
}
@Test
@WithTestEndpointOutcomeExposureContributor
void exposureOutcomeContributorCanMakeEndpointAvailable() {
@ -325,12 +310,6 @@ class ConditionalOnAvailableEndpointTests {
}
@SuppressWarnings({ "deprecation", "removal" })
@Endpoint(id = "disabledbutaccessible", enableByDefault = false)
static class DisabledButAccessibleEndpoint {
}
@EndpointExtension(endpoint = SpringEndpoint.class, filter = TestFilter.class)
static class SpringEndpointExtension {
@ -430,15 +409,4 @@ class ConditionalOnAvailableEndpointTests {
}
@Configuration(proxyBeanMethods = false)
static class DisabledButAccessibleEndpointConfiguration {
@Bean
@ConditionalOnAvailableEndpoint
DisabledButAccessibleEndpoint disabledButAccessible() {
return new DisabledButAccessibleEndpoint();
}
}
}

View File

@ -36,19 +36,6 @@ public abstract class AbstractExposableEndpoint<O extends Operation> implements
private final List<O> operations;
/**
* Create a new {@link AbstractExposableEndpoint} instance.
* @param id the endpoint id
* @param enabledByDefault if the endpoint is enabled by default
* @param operations the endpoint operations
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #AbstractExposableEndpoint(EndpointId, Access, Collection)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public AbstractExposableEndpoint(EndpointId id, boolean enabledByDefault, Collection<? extends O> operations) {
this(id, (enabledByDefault) ? Access.UNRESTRICTED : Access.READ_ONLY, operations);
}
/**
* Create a new {@link AbstractExposableEndpoint} instance.
* @param id the endpoint id
@ -69,13 +56,6 @@ public abstract class AbstractExposableEndpoint<O extends Operation> implements
return this.id;
}
@Override
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
public boolean isEnableByDefault() {
return this.defaultAccess != Access.NONE;
}
@Override
public Access getDefaultAccess() {
return this.defaultAccess;

View File

@ -34,15 +34,6 @@ public interface ExposableEndpoint<O extends Operation> {
*/
EndpointId getEndpointId();
/**
* Returns if the endpoint is enabled by default.
* @return if the endpoint is enabled by default
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #getDefaultAccess()}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
boolean isEnableByDefault();
/**
* Returns the access to the endpoint that is permitted by default.
* @return access that is permitted by default

View File

@ -41,23 +41,6 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation> extends Ab
private final Object endpointBean;
/**
* Create a new {@link AbstractDiscoveredEndpoint} instance.
* @param discoverer the discoverer that discovered the endpoint
* @param endpointBean the primary source bean
* @param id the ID of the endpoint
* @param enabledByDefault if the endpoint is enabled by default
* @param operations the endpoint operations
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #AbstractDiscoveredEndpoint(EndpointDiscoverer, Object, EndpointId, Access, Collection)}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
boolean enabledByDefault, Collection<? extends O> operations) {
this(discoverer, endpointBean, id, (enabledByDefault) ? Access.UNRESTRICTED : Access.READ_ONLY, operations);
}
/**
* Create a new {@link AbstractDiscoveredEndpoint} instance.
* @param discoverer the discoverer that discovered the endpoint

View File

@ -63,14 +63,6 @@ public @interface Endpoint {
*/
String id() default "";
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #defaultAccess()}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -84,21 +84,6 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private volatile Collection<E> endpoints;
/**
* Create a new {@link EndpointDiscoverer} instance.
* @param applicationContext the source application context
* @param parameterValueMapper the parameter value mapper
* @param invokerAdvisors invoker advisors to apply
* @param endpointFilters endpoint filters to apply
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #EndpointDiscoverer(ApplicationContext, ParameterValueMapper, Collection, Collection, Collection)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public EndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
Collection<OperationInvokerAdvisor> invokerAdvisors, Collection<EndpointFilter<E>> endpointFilters) {
this(applicationContext, parameterValueMapper, invokerAdvisors, endpointFilters, Collections.emptyList());
}
/**
* Create a new {@link EndpointDiscoverer} instance.
* @param applicationContext the source application context
@ -381,21 +366,6 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
return (Class<? extends E>) ResolvableType.forClass(EndpointDiscoverer.class, getClass()).resolveGeneric(0);
}
/**
* Factory method called to create the {@link ExposableEndpoint endpoint}.
* @param endpointBean the source endpoint bean
* @param id the ID of the endpoint
* @param enabledByDefault if the endpoint is enabled by default
* @param operations the endpoint operations
* @return a created endpoint (a {@link DiscoveredEndpoint} is recommended)
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #createEndpoint(Object, EndpointId, Access, Collection)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
protected E createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault, Collection<O> operations) {
return createEndpoint(endpointBean, id, (enabledByDefault) ? Access.UNRESTRICTED : Access.NONE, operations);
}
/**
* Factory method called to create the {@link ExposableEndpoint endpoint}.
* @param endpointBean the source endpoint bean
@ -498,8 +468,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
this.beanType = beanType;
this.beanSupplier = beanSupplier;
this.id = EndpointId.of(environment, id);
boolean enabledByDefault = annotation.getBoolean("enableByDefault");
this.defaultAccess = enabledByDefault ? annotation.getEnum("defaultAccess", Access.class) : Access.NONE;
this.defaultAccess = annotation.getEnum("defaultAccess", Access.class);
this.filter = getFilter(beanType);
}

View File

@ -49,7 +49,7 @@ public class OperationMethod {
* @param method the source method
* @param operationType the operation type
* @deprecated since 4.0.0 for removal in 4.2.0 in favor of
* {@link #OperationMethod(Method, OperationType, Predicate)}p
* {@link #OperationMethod(Method, OperationType, Predicate)}
*/
@Deprecated(since = "4.0.0", forRemoval = true)
public OperationMethod(Method method, OperationType operationType) {

View File

@ -48,15 +48,6 @@ public @interface JmxEndpoint {
@AliasFor(annotation = Endpoint.class)
String id() default "";
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
*/
@Deprecated(since = "3.4.0", forRemoval = true)
@AliasFor(annotation = Endpoint.class)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -17,7 +17,6 @@
package org.springframework.boot.actuate.endpoint.jmx.annotation;
import java.util.Collection;
import java.util.Collections;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
@ -48,22 +47,6 @@ import org.springframework.context.annotation.ImportRuntimeHints;
public class JmxEndpointDiscoverer extends EndpointDiscoverer<ExposableJmxEndpoint, JmxOperation>
implements JmxEndpointsSupplier {
/**
* Create a new {@link JmxEndpointDiscoverer} instance.
* @param applicationContext the source application context
* @param parameterValueMapper the parameter value mapper
* @param invokerAdvisors invoker advisors to apply
* @param endpointFilters endpoint filters to apply
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #JmxEndpointDiscoverer(ApplicationContext, ParameterValueMapper, Collection, Collection, Collection)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public JmxEndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
Collection<OperationInvokerAdvisor> invokerAdvisors,
Collection<EndpointFilter<ExposableJmxEndpoint>> endpointFilters) {
this(applicationContext, parameterValueMapper, invokerAdvisors, endpointFilters, Collections.emptyList());
}
/**
* Create a new {@link JmxEndpointDiscoverer} instance.
* @param applicationContext the source application context

View File

@ -65,13 +65,6 @@ public @interface ControllerEndpoint {
@AliasFor(annotation = Endpoint.class)
String id();
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
*/
@AliasFor(annotation = Endpoint.class)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -67,13 +67,6 @@ public @interface RestControllerEndpoint {
@AliasFor(annotation = Endpoint.class)
String id();
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
*/
@AliasFor(annotation = Endpoint.class)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -58,13 +58,6 @@ public @interface ServletEndpoint {
@AliasFor(annotation = Endpoint.class)
String id();
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
*/
@AliasFor(annotation = Endpoint.class)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -48,15 +48,6 @@ public @interface WebEndpoint {
@AliasFor(annotation = Endpoint.class)
String id();
/**
* If the endpoint should be enabled or disabled by default.
* @return {@code true} if the endpoint is enabled by default
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #defaultAccess()}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
@AliasFor(annotation = Endpoint.class)
boolean enableByDefault() default true;
/**
* Level of access to the endpoint that is permitted by default.
* @return the default level of access

View File

@ -59,26 +59,6 @@ public class WebEndpointDiscoverer extends EndpointDiscoverer<ExposableWebEndpoi
private final RequestPredicateFactory requestPredicateFactory;
/**
* Create a new {@link WebEndpointDiscoverer} instance.
* @param applicationContext the source application context
* @param parameterValueMapper the parameter value mapper
* @param endpointMediaTypes the endpoint media types
* @param endpointPathMappers the endpoint path mappers
* @param invokerAdvisors invoker advisors to apply
* @param filters filters to apply
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #WebEndpointDiscoverer(ApplicationContext, ParameterValueMapper, EndpointMediaTypes, List, List, Collection, Collection, Collection)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public WebEndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
EndpointMediaTypes endpointMediaTypes, List<PathMapper> endpointPathMappers,
Collection<OperationInvokerAdvisor> invokerAdvisors,
Collection<EndpointFilter<ExposableWebEndpoint>> filters) {
this(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, Collections.emptyList(),
invokerAdvisors, filters, Collections.emptyList());
}
/**
* Create a new {@link WebEndpointDiscoverer} instance.
* @param applicationContext the source application context

View File

@ -562,13 +562,6 @@ class EndpointDiscovererTests {
return new TestExposableEndpoint(this, endpointBean, id, defaultAccess, operations);
}
@Override
@SuppressWarnings("removal")
protected TestExposableEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault,
Collection<TestOperation> operations) {
return new TestExposableEndpoint(this, endpointBean, id, enabledByDefault, operations);
}
@Override
protected TestOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
OperationInvoker invoker) {
@ -603,13 +596,6 @@ class EndpointDiscovererTests {
return new SpecializedExposableEndpoint(this, endpointBean, id, defaultAccess, operations);
}
@Override
@SuppressWarnings("removal")
protected SpecializedExposableEndpoint createEndpoint(Object endpointBean, EndpointId id,
boolean enabledByDefault, Collection<SpecializedOperation> operations) {
return new SpecializedExposableEndpoint(this, endpointBean, id, enabledByDefault, operations);
}
@Override
protected SpecializedOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
OperationInvoker invoker) {
@ -631,12 +617,6 @@ class EndpointDiscovererTests {
super(discoverer, endpointBean, id, defaultAccess, operations);
}
@SuppressWarnings("removal")
TestExposableEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
boolean enabledByDefault, Collection<? extends TestOperation> operations) {
super(discoverer, endpointBean, id, enabledByDefault, operations);
}
}
static class SpecializedExposableEndpoint extends AbstractDiscoveredEndpoint<SpecializedOperation> {
@ -647,12 +627,6 @@ class EndpointDiscovererTests {
super(discoverer, endpointBean, id, defaultAccess, operations);
}
@SuppressWarnings("removal")
SpecializedExposableEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
boolean enabledByDefault, Collection<? extends SpecializedOperation> operations) {
super(discoverer, endpointBean, id, enabledByDefault, operations);
}
}
static class TestOperation extends AbstractDiscoveredOperation {

View File

@ -44,12 +44,6 @@ public class TestExposableJmxEndpoint implements ExposableJmxEndpoint {
return EndpointId.of("test");
}
@Override
@SuppressWarnings("removal")
public boolean isEnableByDefault() {
return true;
}
@Override
public Collection<JmxOperation> getOperations() {
return this.operations;

View File

@ -63,7 +63,6 @@ class EndpointLinksResolverTests {
operations.add(operationWithPath("/alpha/{name}", "alpha-name"));
ExposableWebEndpoint endpoint = mock(ExposableWebEndpoint.class);
given(endpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
given(endpoint.isEnableByDefault()).willReturn(true);
given(endpoint.getOperations()).willReturn(operations);
String requestUrl = "https://api.example.com/actuator";
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(endpoint))
@ -80,7 +79,6 @@ class EndpointLinksResolverTests {
void resolvedLinksContainsALinkForServletEndpoint() {
ExposableServletEndpoint servletEndpoint = mock(ExposableServletEndpoint.class);
given(servletEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
given(servletEndpoint.isEnableByDefault()).willReturn(true);
given(servletEndpoint.getRootPath()).willReturn("alpha");
String requestUrl = "https://api.example.com/actuator";
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(servletEndpoint))
@ -94,7 +92,6 @@ class EndpointLinksResolverTests {
void resolvedLinksContainsALinkForControllerEndpoint() {
ExposableControllerEndpoint controllerEndpoint = mock(ExposableControllerEndpoint.class);
given(controllerEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha"));
given(controllerEndpoint.isEnableByDefault()).willReturn(true);
given(controllerEndpoint.getRootPath()).willReturn("alpha");
String requestUrl = "https://api.example.com/actuator";
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(controllerEndpoint))

View File

@ -148,17 +148,4 @@ public class ConditionOutcome {
return (this.message != null) ? this.message.toString() : "";
}
/**
* Return the inverse of the specified condition outcome.
* @param outcome the outcome to inverse
* @return the inverse of the condition outcome
* @since 1.3.0
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
* {@link #ConditionOutcome(boolean, ConditionMessage)}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
public static ConditionOutcome inverse(ConditionOutcome outcome) {
return new ConditionOutcome(!outcome.isMatch(), outcome.getConditionMessage());
}
}

View File

@ -48,16 +48,6 @@ public class ConnectionDetailsFactories {
private final List<Registration<?, ?>> registrations = new ArrayList<>();
/**
* Create a new {@link ConnectionDetailsFactories} instance.
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
* {@link #ConnectionDetailsFactories(ClassLoader)}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
public ConnectionDetailsFactories() {
this((ClassLoader) null);
}
/**
* Create a new {@link ConnectionDetailsFactories} instance.
* @param classLoader the class loader used to load factories

View File

@ -120,11 +120,6 @@ public class JobLauncherApplicationRunner
}
}
@Deprecated(since = "3.0.10", forRemoval = true)
public void validate() {
afterPropertiesSet();
}
public void setOrder(int order) {
this.order = order;
}

View File

@ -1,69 +0,0 @@
/*
* Copyright 2012-present 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.boot.cassandra.testcontainers;
import com.datastax.oss.driver.api.core.CqlSession;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.CassandraContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedCassandraContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final CassandraContainer<?> cassandra = TestImage.container(CassandraContainer.class);
@Autowired(required = false)
private CassandraConnectionDetails connectionDetails;
@Autowired
private CqlSession cqlSession;
@Test
void connectionCanBeMadeToCassandraContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.cqlSession.getMetadata().getNodes()).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(CassandraAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright 2012-present 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.boot.cassandra.testcontainers;
import java.net.InetSocketAddress;
import java.util.List;
import org.testcontainers.containers.CassandraContainer;
import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
/**
* {@link ContainerConnectionDetailsFactory} to create {@link CassandraConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link CassandraContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link CassandraContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<CassandraContainer<?>, CassandraConnectionDetails> {
@Override
protected CassandraConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<CassandraContainer<?>> source) {
return new CassandraContainerConnectionDetails(source);
}
/**
* {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class CassandraContainerConnectionDetails
extends ContainerConnectionDetails<CassandraContainer<?>> implements CassandraConnectionDetails {
private CassandraContainerConnectionDetails(ContainerConnectionSource<CassandraContainer<?>> source) {
super(source);
}
@Override
public List<Node> getContactPoints() {
InetSocketAddress contactPoint = getContainer().getContactPoint();
return List.of(new Node(contactPoint.getHostString(), contactPoint.getPort()));
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getLocalDatacenter() {
return getContainer().getLocalDatacenter();
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
}
}

View File

@ -1,5 +1,4 @@
# Connection Details Factories
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
org.springframework.boot.cassandra.docker.compose.CassandraDockerComposeConnectionDetailsFactory,\
org.springframework.boot.cassandra.testcontainers.CassandraContainerConnectionDetailsFactory,\
org.springframework.boot.cassandra.testcontainers.DeprecatedCassandraContainerConnectionDetailsFactory
org.springframework.boot.cassandra.testcontainers.CassandraContainerConnectionDetailsFactory

View File

@ -27,12 +27,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
* A condition that checks if DevTools should be enabled.
*
* @author Madhura Bhave
* @since 2.2.0
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
* {@link ConditionalOnEnabledDevTools @ConditionalOnEnabledDevTools}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
public class OnEnabledDevToolsCondition extends SpringBootCondition {
class OnEnabledDevToolsCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {

View File

@ -278,8 +278,6 @@ public class FlywayAutoConfiguration {
map.from(properties.isBaselineOnMigrate())
.to((baselineOnMigrate) -> configuration.baselineOnMigrate(baselineOnMigrate));
map.from(properties.isCleanDisabled()).to((cleanDisabled) -> configuration.cleanDisabled(cleanDisabled));
map.from(properties.isCleanOnValidationError())
.to((cleanOnValidationError) -> configuration.cleanOnValidationError(cleanOnValidationError));
map.from(properties.isGroup()).to((group) -> configuration.group(group));
map.from(properties.isMixed()).to((mixed) -> configuration.mixed(mixed));
map.from(properties.isOutOfOrder()).to((outOfOrder) -> configuration.outOfOrder(outOfOrder));

View File

@ -28,7 +28,6 @@ import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.convert.DurationUnit;
/**
@ -211,11 +210,6 @@ public class FlywayProperties {
*/
private boolean cleanDisabled = true;
/**
* Whether to automatically call clean when a validation error occurs.
*/
private boolean cleanOnValidationError;
/**
* Whether to group all pending migrations together in the same transaction when
* applying them.
@ -595,17 +589,6 @@ public class FlywayProperties {
this.cleanDisabled = cleanDisabled;
}
@Deprecated(since = "3.4.0", forRemoval = true)
@DeprecatedConfigurationProperty(since = "3.4.0", reason = "Deprecated in Flyway 10.18 and removed in Flyway 11.0")
public boolean isCleanOnValidationError() {
return this.cleanOnValidationError;
}
@Deprecated(since = "3.4.0", forRemoval = true)
public void setCleanOnValidationError(boolean cleanOnValidationError) {
this.cleanOnValidationError = cleanOnValidationError;
}
public boolean isGroup() {
return this.group;
}
@ -718,39 +701,6 @@ public class FlywayProperties {
this.errorOverrides = errorOverrides;
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.sqlplus", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public Boolean getOracleSqlplus() {
return getOracle().getSqlplus();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setOracleSqlplus(Boolean oracleSqlplus) {
getOracle().setSqlplus(oracleSqlplus);
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.sqlplus-warn", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public Boolean getOracleSqlplusWarn() {
return getOracle().getSqlplusWarn();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setOracleSqlplusWarn(Boolean oracleSqlplusWarn) {
getOracle().setSqlplusWarn(oracleSqlplusWarn);
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.wallet-location", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public String getOracleWalletLocation() {
return getOracle().getWalletLocation();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setOracleWalletLocation(String oracleWalletLocation) {
getOracle().setWalletLocation(oracleWalletLocation);
}
public Boolean getStream() {
return this.stream;
}
@ -775,17 +725,6 @@ public class FlywayProperties {
this.kerberosConfigFile = kerberosConfigFile;
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.kerberos-cache-file", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public String getOracleKerberosCacheFile() {
return getOracle().getKerberosCacheFile();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setOracleKerberosCacheFile(String oracleKerberosCacheFile) {
getOracle().setKerberosCacheFile(oracleKerberosCacheFile);
}
public Boolean getOutputQueryResults() {
return this.outputQueryResults;
}
@ -794,17 +733,6 @@ public class FlywayProperties {
this.outputQueryResults = outputQueryResults;
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.sqlserver.kerberos-login-file")
@Deprecated(since = "3.2.0", forRemoval = true)
public String getSqlServerKerberosLoginFile() {
return getSqlserver().getKerberosLoginFile();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setSqlServerKerberosLoginFile(String sqlServerKerberosLoginFile) {
getSqlserver().setKerberosLoginFile(sqlServerKerberosLoginFile);
}
public Boolean getSkipExecutingMigrations() {
return this.skipExecutingMigrations;
}

View File

@ -24,7 +24,18 @@
"level": "error",
"reason": "Removed in Flyway 10"
}
},{
},
{
"name": "spring.flyway.clean-on-validation-error",
"type": "java.lang.Boolean",
"description": "Whether to automatically call clean when a validation error occurs.",
"deprecation": {
"level": "error",
"reason": "Deprecated in Flyway 10.18 and removed in Flyway 11.0",
"since": "3.4.0"
}
},
{
"name": "spring.flyway.community-db-support-enabled",
"defaultValue": false
},
@ -94,11 +105,20 @@
},
{
"name": "spring.flyway.locations",
"sourceType": "org.springframework.boot.autoconfigure.flyway.FlywayProperties",
"sourceType": "org.springframework.boot.flyway.autoconfigure.FlywayProperties",
"defaultValue": [
"classpath:db/migration"
]
},
{
"name": "spring.flyway.oracle-kerberos-cache-file",
"type": "java.lang.String",
"deprecation": {
"replacement": "spring.flyway.oracle.kerberos-cache-file",
"level": "error",
"since": "3.2.0"
}
},
{
"name": "spring.flyway.oracle-kerberos-config-file",
"type": "java.lang.String",
@ -107,6 +127,33 @@
"level": "error"
}
},
{
"name": "spring.flyway.oracle-sqlplus",
"type": "java.lang.Boolean",
"deprecation": {
"replacement": "spring.flyway.oracle.sqlplus",
"level": "error",
"since": "3.2.0"
}
},
{
"name": "spring.flyway.oracle-sqlplus-warn",
"type": "java.lang.Boolean",
"deprecation": {
"replacement": "spring.flyway.oracle.sqlplus-warn",
"level": "error",
"since": "3.2.0"
}
},
{
"name": "spring.flyway.oracle-wallet-location",
"type": "java.lang.String",
"deprecation": {
"replacement": "spring.flyway.oracle.wallet-location",
"level": "error",
"since": "3.2.0"
}
},
{
"name": "spring.flyway.sql-migration-suffix",
"type": "java.lang.String",
@ -117,11 +164,19 @@
},
{
"name": "spring.flyway.sql-migration-suffixes",
"sourceType": "org.springframework.boot.autoconfigure.flyway.FlywayProperties",
"sourceType": "org.springframework.boot.flyway.autoconfigure.FlywayProperties",
"defaultValue": [
".sql"
]
},
{
"name": "spring.flyway.sql-server-kerberos-login-file",
"type": "java.lang.String",
"deprecation": {
"replacement": "spring.flyway.sqlserver.kerberos-login-file",
"level": "error"
}
},
{
"name": "spring.flyway.undo-sql-migration-prefix",
"type": "java.lang.String",

View File

@ -643,19 +643,6 @@ class FlywayAutoConfigurationTests {
}
@Test
@Deprecated(since = "3.2.0", forRemoval = true)
void oracleSqlplusIsCorrectlyMappedWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-sqlplus=true")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getSqlplus()).isTrue());
}
@Test
void oracleSqlplusWarnIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -667,18 +654,6 @@ class FlywayAutoConfigurationTests {
.getSqlplusWarn()).isTrue());
}
@Test
@Deprecated(since = "3.2.0", forRemoval = true)
void oracleSqlplusWarnIsCorrectlyMappedWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-sqlplus-warn=true")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getSqlplusWarn()).isTrue());
}
@Test
void oracleWallerLocationIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -690,18 +665,6 @@ class FlywayAutoConfigurationTests {
.getWalletLocation()).isEqualTo("/tmp/my.wallet"));
}
@Test
@Deprecated(since = "3.2.0", forRemoval = true)
void oracleWallerLocationIsCorrectlyMappedWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-wallet-location=/tmp/my.wallet")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getWalletLocation()).isEqualTo("/tmp/my.wallet"));
}
@Test
void oracleKerberosCacheFileIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -713,18 +676,6 @@ class FlywayAutoConfigurationTests {
.getKerberosCacheFile()).isEqualTo("/tmp/cache"));
}
@Test
@Deprecated(since = "3.2.0", forRemoval = true)
void oracleKerberosCacheFileIsCorrectlyMappedWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.oracle-kerberos-cache-file=/tmp/cache")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(OracleConfigurationExtension.class)
.getKerberosCacheFile()).isEqualTo("/tmp/cache"));
}
@Test
void streamIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@ -835,20 +786,6 @@ class FlywayAutoConfigurationTests {
.getFile()).isEqualTo("/tmp/config"));
}
@Test
@Deprecated(since = "3.2.0", forRemoval = true)
void sqlServerKerberosLoginFileIsCorrectlyMappedWithDeprecatedProperty() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.flyway.sql-server-kerberos-login-file=/tmp/config")
.run((context) -> assertThat(context.getBean(Flyway.class)
.getConfiguration()
.getPluginRegister()
.getPlugin(SQLServerConfigurationExtension.class)
.getKerberos()
.getLogin()
.getFile()).isEqualTo("/tmp/config"));
}
@Test
void skipExecutingMigrationsIsCorrectlyMapped() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)

View File

@ -81,7 +81,6 @@ class FlywayPropertiesTests {
assertThat(properties.getInitSqls()).isEmpty();
assertThat(properties.isBaselineOnMigrate()).isEqualTo(configuration.isBaselineOnMigrate());
assertThat(properties.isCleanDisabled()).isEqualTo(configuration.isCleanDisabled());
assertThat(properties.isCleanOnValidationError()).isEqualTo(configuration.isCleanOnValidationError());
assertThat(properties.isGroup()).isEqualTo(configuration.isGroup());
assertThat(properties.isMixed()).isEqualTo(configuration.isMixed());
assertThat(properties.isOutOfOrder()).isEqualTo(configuration.isOutOfOrder());
@ -111,9 +110,6 @@ class FlywayPropertiesTests {
PropertyAccessorFactory.forBeanPropertyAccess(new ClassicConfiguration()));
// Properties specific settings
ignoreProperties(properties, "url", "driverClassName", "user", "password", "enabled");
// Deprecated properties
ignoreProperties(properties, "oracleKerberosCacheFile", "oracleSqlplus", "oracleSqlplusWarn",
"oracleWalletLocation", "sqlServerKerberosLoginFile");
// Properties that are managed by specific extensions
ignoreProperties(properties, "oracle", "postgresql", "sqlserver");
// Properties that are only used on the command line
@ -127,7 +123,7 @@ class FlywayPropertiesTests {
ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames", "driver", "modernConfig",
"currentResolvedEnvironment", "reportFilename", "reportEnabled", "workingDirectory",
"cachedDataSources", "cachedResolvedEnvironments", "currentEnvironmentName", "allEnvironments",
"environmentProvisionMode", "provisionMode");
"environmentProvisionMode", "provisionMode", "cleanOnValidationError");
// Handled by the conversion service
ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings",
"targetAsString");

View File

@ -20,7 +20,6 @@ import java.time.Duration;
import java.util.Arrays;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.core.io.Resource;
/**
@ -40,8 +39,6 @@ public class GraphQlProperties {
private final Schema schema = new Schema();
private final DeprecatedSse sse = new DeprecatedSse(this.http.getSse());
private final Websocket websocket = new Websocket();
public Http getHttp() {
@ -52,17 +49,6 @@ public class GraphQlProperties {
return this.graphiql;
}
@DeprecatedConfigurationProperty(replacement = "spring.graphql.http.path", since = "3.5.0")
@Deprecated(since = "3.5.0", forRemoval = true)
public String getPath() {
return getHttp().getPath();
}
@Deprecated(since = "3.5.0", forRemoval = true)
public void setPath(String path) {
getHttp().setPath(path);
}
public Schema getSchema() {
return this.schema;
}
@ -75,10 +61,6 @@ public class GraphQlProperties {
return this.rsocket;
}
public DeprecatedSse getSse() {
return this.sse;
}
public static class Http {
/**
@ -343,26 +325,4 @@ public class GraphQlProperties {
}
@Deprecated(since = "3.5.1", forRemoval = true)
public static final class DeprecatedSse {
private final Sse sse;
private DeprecatedSse(Sse sse) {
this.sse = sse;
}
@DeprecatedConfigurationProperty(replacement = "spring.graphql.http.sse.timeout", since = "3.5.0")
@Deprecated(since = "3.5.0", forRemoval = true)
public Duration getTimeout() {
return this.sse.getTimeout();
}
@Deprecated(since = "3.5.0", forRemoval = true)
public void setTimeout(Duration timeout) {
this.sse.setTimeout(timeout);
}
}
}

View File

@ -27,6 +27,16 @@
"reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram."
}
},
{
"name": "spring.graphql.path",
"type": "java.lang.String",
"deprecated": true,
"deprecation": {
"level": "error",
"replacement": "spring.graphql.http.path",
"since": "3.5.0"
}
},
{
"name": "spring.graphql.schema.file-extensions",
"defaultValue": ".graphqls,.gqls"
@ -34,6 +44,16 @@
{
"name": "spring.graphql.schema.locations",
"defaultValue": "classpath:graphql/**/"
},
{
"name": "spring.graphql.sse.timeout",
"type": "java.time.Duration",
"deprecated": true,
"deprecation": {
"level": "error",
"replacement": "spring.graphql.http.sse.timeout",
"since": "3.5.0"
}
}
],
"hints": [

View File

@ -187,13 +187,6 @@ class GroovyTemplateAutoConfigurationTests {
assertThat(writer.toString()).contains("Hello World");
}
@Test
@Deprecated(since = "3.5.0", forRemoval = true)
void customConfiguration() {
registerAndRefreshContext("spring.groovy.template.configuration.auto-indent:true");
assertThat(this.context.getBean(GroovyMarkupConfigurer.class).isAutoIndent()).isTrue();
}
@Test
void enableAutoEscape() {
registerAndRefreshContext("spring.groovy.template.auto-escape:true");

View File

@ -21,7 +21,6 @@ import com.google.gson.Gson;
import com.google.gson.LongSerializationPolicy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
/**
* Configuration properties to configure {@link Gson}.
@ -163,12 +162,6 @@ public class GsonProperties {
this.strictness = strictness;
}
@Deprecated(since = "3.4.0", forRemoval = true)
@DeprecatedConfigurationProperty(replacement = "spring.gson.strictness", since = "3.4.0")
public Boolean getLenient() {
return (this.strictness != null) && (this.strictness == Strictness.LENIENT);
}
public void setLenient(Boolean lenient) {
setStrictness((lenient != null && lenient) ? Strictness.LENIENT : Strictness.STRICT);
}

View File

@ -0,0 +1,13 @@
{
"groups": [],
"properties": [
{
"name": "spring.gson.lenient",
"type": "java.lang.Boolean",
"deprecation": {
"replacement": "spring.gson.strictness",
"since": "3.4.0"
}
}
]
}

View File

@ -46,33 +46,6 @@ class Gson210AutoConfigurationTests {
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withoutLenient() {
this.contextRunner.run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("lenient", false);
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withLenientTrue() {
this.contextRunner.withPropertyValues("spring.gson.lenient:true").run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("lenient", true);
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withLenientFalse() {
this.contextRunner.withPropertyValues("spring.gson.lenient:false").run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("lenient", false);
});
}
public class DataObject {
@SuppressWarnings("unused")

View File

@ -209,33 +209,6 @@ class GsonAutoConfigurationTests {
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withoutLenient() {
this.contextRunner.run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("strictness", null);
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withLenientTrue() {
this.contextRunner.withPropertyValues("spring.gson.lenient:true").run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("strictness", Strictness.LENIENT);
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void withLenientFalse() {
this.contextRunner.withPropertyValues("spring.gson.lenient:false").run((context) -> {
Gson gson = context.getBean(Gson.class);
assertThat(gson).hasFieldOrPropertyWithValue("strictness", Strictness.STRICT);
});
}
@Test
void withoutStrictness() {
this.contextRunner.run((context) -> {

View File

@ -75,20 +75,6 @@ public class HikariCheckpointRestoreLifecycle implements Lifecycle {
private final ConfigurableApplicationContext applicationContext;
/**
* Creates a new {@code HikariCheckpointRestoreLifecycle} that will allow the given
* {@code dataSource} to participate in checkpoint-restore. The {@code dataSource} is
* {@link DataSourceUnwrapper#unwrap unwrapped} to a {@link HikariDataSource}. If such
* unwrapping is not possible, the lifecycle will have no effect.
* @param dataSource the checkpoint-restore participant
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #HikariCheckpointRestoreLifecycle(DataSource, ConfigurableApplicationContext)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public HikariCheckpointRestoreLifecycle(DataSource dataSource) {
this(dataSource, null);
}
/**
* Creates a new {@code HikariCheckpointRestoreLifecycle} that will allow the given
* {@code dataSource} to participate in checkpoint-restore. The {@code dataSource} is

View File

@ -105,12 +105,8 @@ public final class DefaultJmsListenerContainerFactoryConfigurer {
/**
* Set the {@link ObservationRegistry} to use.
* @param observationRegistry the {@link ObservationRegistry}
* @since 3.2.1
* @deprecated since 3.3.10 for removal in 4.0.0 as this should have been package
* private
*/
@Deprecated(since = "3.3.10", forRemoval = true)
public void setObservationRegistry(ObservationRegistry observationRegistry) {
void setObservationRegistry(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}

View File

@ -19,7 +19,6 @@ package org.springframework.boot.jms.autoconfigure;
import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
/**
* Configuration properties for JMS.
@ -203,28 +202,6 @@ public class JmsProperties {
this.autoStartup = autoStartup;
}
@Deprecated(since = "3.2.0", forRemoval = true)
@DeprecatedConfigurationProperty(replacement = "spring.jms.listener.session.acknowledge-mode", since = "3.2.0")
public AcknowledgeMode getAcknowledgeMode() {
return this.session.getAcknowledgeMode();
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
this.session.setAcknowledgeMode(acknowledgeMode);
}
@DeprecatedConfigurationProperty(replacement = "spring.jms.listener.min-concurrency", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public Integer getConcurrency() {
return this.minConcurrency;
}
@Deprecated(since = "3.2.0", forRemoval = true)
public void setConcurrency(Integer concurrency) {
this.minConcurrency = concurrency;
}
public Integer getMinConcurrency() {
return this.minConcurrency;
}

View File

@ -6,6 +6,21 @@
"type": "java.lang.Boolean",
"description": "Whether to enable JMS health check.",
"defaultValue": true
},
{
"name": "spring.jms.listener.acknowledge-mode",
"deprecation": {
"replacement": "spring.jms.listener.session.acknowledge-mode",
"since": "3.2.0"
}
},
{
"name": "spring.jms.listener.concurrency",
"type": "java.lang.Integer",
"deprecation": {
"replacement": "spring.jms.listener.min-concurrency",
"since": "3.2.0"
}
}
],
"hints": [

View File

@ -99,41 +99,6 @@ public class EntityManagerFactoryBuilder {
this.persistenceUnitRootLocation = persistenceUnitRootLocation;
}
/**
* Create a new instance passing in the common pieces that will be shared if multiple
* EntityManagerFactory instances are created.
* @param jpaVendorAdapter a vendor adapter
* @param jpaProperties the JPA properties to be passed to the persistence provider
* @param persistenceUnitManager optional source of persistence unit information (can
* be null)
* @deprecated since 3.4.4 for removal in 4.0.0 in favor of
* {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager)}
*/
@Deprecated(since = "3.4.4", forRemoval = true)
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
PersistenceUnitManager persistenceUnitManager) {
this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, null);
}
/**
* Create a new instance passing in the common pieces that will be shared if multiple
* EntityManagerFactory instances are created.
* @param jpaVendorAdapter a vendor adapter
* @param jpaProperties the JPA properties to be passed to the persistence provider
* @param persistenceUnitManager optional source of persistence unit information (can
* be null)
* @param persistenceUnitRootLocation the persistence unit root location to use as a
* fallback or {@code null}
* @since 1.4.1
* @deprecated since 3.4.4 for removal in 4.0.0 in favor of
* {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager, URL)}
*/
@Deprecated(since = "3.4.4", forRemoval = true)
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
PersistenceUnitManager persistenceUnitManager, URL persistenceUnitRootLocation) {
this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, persistenceUnitRootLocation);
}
/**
* Create a new {@link Builder} for a {@code EntityManagerFactory} using the settings
* of the given instance, and the given {@link DataSource}.

View File

@ -156,17 +156,6 @@ public abstract class JpaBaseConfiguration {
*/
protected abstract Map<String, Object> getVendorProperties(DataSource dataSource);
/**
* Return the vendor-specific properties.
* @return the vendor properties
* @deprecated since 3.4.4 for removal in 4.0.0 in favor of
* {@link #getVendorProperties(DataSource)}
*/
@Deprecated(since = "3.4.4", forRemoval = true)
protected Map<String, Object> getVendorProperties() {
return getVendorProperties(getDataSource());
}
/**
* Customize vendor properties before they are used. Allows for post-processing (for
* example to configure JTA specific settings).

View File

@ -1,97 +0,0 @@
/*
* Copyright 2012-present 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.boot.kafka.testcontainers;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedConfluentKafkaContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final KafkaContainer kafka = TestImage.container(KafkaContainer.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@ -85,46 +85,6 @@ public interface KafkaConnectionDetails extends ConnectionDetails {
return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol());
}
/**
* Returns the list of bootstrap servers used for consumers.
* @return the list of bootstrap servers used for consumers
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getConsumer()}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
default List<String> getConsumerBootstrapServers() {
return getConsumer().getBootstrapServers();
}
/**
* Returns the list of bootstrap servers used for producers.
* @return the list of bootstrap servers used for producers
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getProducer()}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
default List<String> getProducerBootstrapServers() {
return getProducer().getBootstrapServers();
}
/**
* Returns the list of bootstrap servers used for the admin.
* @return the list of bootstrap servers used for the admin
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getAdmin()}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
default List<String> getAdminBootstrapServers() {
return getAdmin().getBootstrapServers();
}
/**
* Returns the list of bootstrap servers used for Kafka Streams.
* @return the list of bootstrap servers used for Kafka Streams
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getStreams()}
*/
@Deprecated(since = "3.5.0", forRemoval = true)
default List<String> getStreamsBootstrapServers() {
return getStreams().getBootstrapServers();
}
/**
* Kafka connection details configuration.
*/

View File

@ -34,7 +34,6 @@ import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException;
import org.springframework.boot.convert.DurationUnit;
@ -1585,51 +1584,6 @@ public class KafkaProperties {
this.attempts = attempts;
}
@DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.delay", since = "3.4.0")
@Deprecated(since = "3.4.0", forRemoval = true)
public Duration getDelay() {
return getBackoff().getDelay();
}
@Deprecated(since = "3.4.0", forRemoval = true)
public void setDelay(Duration delay) {
getBackoff().setDelay(delay);
}
@DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.multiplier",
since = "3.4.0")
@Deprecated(since = "3.4.0", forRemoval = true)
public double getMultiplier() {
return getBackoff().getMultiplier();
}
@Deprecated(since = "3.4.0", forRemoval = true)
public void setMultiplier(double multiplier) {
getBackoff().setMultiplier(multiplier);
}
@DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.maxDelay", since = "3.4.0")
@Deprecated(since = "3.4.0", forRemoval = true)
public Duration getMaxDelay() {
return getBackoff().getMaxDelay();
}
@Deprecated(since = "3.4.0", forRemoval = true)
public void setMaxDelay(Duration maxDelay) {
getBackoff().setMaxDelay(maxDelay);
}
@DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.random", since = "3.4.0")
@Deprecated(since = "3.4.0", forRemoval = true)
public boolean isRandomBackOff() {
return getBackoff().isRandom();
}
@Deprecated(since = "3.4.0", forRemoval = true)
public void setRandomBackOff(boolean randomBackOff) {
getBackoff().setRandom(randomBackOff);
}
private final Backoff backoff = new Backoff();
public Backoff getBackoff() {

View File

@ -1,75 +0,0 @@
/*
* Copyright 2012-present 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.boot.kafka.testcontainers;
import java.util.List;
import org.testcontainers.containers.KafkaContainer;
import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
/**
* {@link ContainerConnectionDetailsFactory} to create {@link KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link KafkaContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link ConfluentKafkaContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<KafkaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
return new ConfluentKafkaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ConfluentKafkaContainerConnectionDetails
extends ContainerConnectionDetails<KafkaContainer> implements KafkaConnectionDetails {
private ConfluentKafkaContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
@Override
public SslBundle getSslBundle() {
return super.getSslBundle();
}
@Override
public String getSecurityProtocol() {
return (getSslBundle() != null) ? "SSL" : "PLAINTEXT";
}
}
}

View File

@ -118,6 +118,38 @@
"level": "error"
}
},
{
"name": "spring.kafka.retry.topic.delay",
"type": "java.time.Duration",
"deprecation": {
"replacement": "spring.kafka.retry.topic.backoff.delay",
"since": "3.4.0"
}
},
{
"name": "spring.kafka.retry.topic.max-delay",
"type": "java.time.Duration",
"deprecation": {
"replacement": "spring.kafka.retry.topic.backoff.maxDelay",
"since": "3.4.0"
}
},
{
"name": "spring.kafka.retry.topic.multiplier",
"type": "java.lang.Double",
"deprecation": {
"replacement": "spring.kafka.retry.topic.backoff.multiplier",
"since": "3.4.0"
}
},
{
"name": "spring.kafka.retry.topic.random-back-off",
"type": "java.lang.Boolean",
"deprecation": {
"replacement": "spring.kafka.retry.topic.backoff.random",
"since": "3.4.0"
}
},
{
"name": "spring.kafka.ssl.keystore-location",
"type": "org.springframework.core.io.Resource",

View File

@ -2,5 +2,4 @@
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
org.springframework.boot.kafka.testcontainers.ApacheKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.kafka.testcontainers.ConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.kafka.testcontainers.DeprecatedConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.kafka.testcontainers.RedpandaContainerConnectionDetailsFactory

View File

@ -103,8 +103,8 @@ class KafkaAutoConfigurationIntegrationTests {
void testEndToEndWithRetryTopics() throws Exception {
load(KafkaConfig.class, "spring.kafka.bootstrap-servers:" + getEmbeddedKafkaBrokersAsString(),
"spring.kafka.consumer.group-id=testGroup", "spring.kafka.retry.topic.enabled=true",
"spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.delay=100ms",
"spring.kafka.retry.topic.multiplier=2", "spring.kafka.retry.topic.max-delay=300ms",
"spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.backoff.delay=100ms",
"spring.kafka.retry.topic.backoff.multiplier=2", "spring.kafka.retry.topic.backoff.max-delay=300ms",
"spring.kafka.consumer.auto-offset-reset=earliest");
RetryTopicConfiguration configuration = this.context.getBean(RetryTopicConfiguration.class);
assertThat(configuration.getDestinationTopicProperties()).extracting(DestinationTopic.Properties::delay)

View File

@ -566,22 +566,6 @@ class KafkaAutoConfigurationTests {
});
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void retryTopicConfigurationWithExponentialBackOffUsingDeprecatedProperties() {
this.contextRunner.withPropertyValues("spring.application.name=my-test-app",
"spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true",
"spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.delay=100ms",
"spring.kafka.retry.topic.multiplier=2", "spring.kafka.retry.topic.max-delay=300ms")
.run((context) -> {
RetryTopicConfiguration configuration = context.getBean(RetryTopicConfiguration.class);
assertThat(configuration.getDestinationTopicProperties()).hasSize(5)
.extracting(DestinationTopic.Properties::delay, DestinationTopic.Properties::suffix)
.containsExactly(tuple(0L, ""), tuple(100L, "-retry-0"), tuple(200L, "-retry-1"),
tuple(300L, "-retry-2"), tuple(0L, "-dlt"));
});
}
@Test
void retryTopicConfigurationWithDefaultProperties() {
this.contextRunner.withPropertyValues("spring.application.name=my-test-app",
@ -607,18 +591,6 @@ class KafkaAutoConfigurationTests {
.containsExactly(0L, 2000L, 0L)));
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void retryTopicConfigurationWithFixedBackOffUsingDeprecatedProperties() {
this.contextRunner.withPropertyValues("spring.application.name=my-test-app",
"spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true",
"spring.kafka.retry.topic.attempts=4", "spring.kafka.retry.topic.delay=2s")
.run(assertRetryTopicConfiguration(
(configuration) -> assertThat(configuration.getDestinationTopicProperties()).hasSize(3)
.extracting(DestinationTopic.Properties::delay)
.containsExactly(0L, 2000L, 0L)));
}
@Test
void retryTopicConfigurationWithNoBackOff() {
this.contextRunner.withPropertyValues("spring.application.name=my-test-app",
@ -630,18 +602,6 @@ class KafkaAutoConfigurationTests {
.containsExactly(0L, 0L, 0L)));
}
@Test
@Deprecated(since = "3.4.0", forRemoval = true)
void retryTopicConfigurationWithNoBackOffUsingDeprecatedProperties() {
this.contextRunner.withPropertyValues("spring.application.name=my-test-app",
"spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true",
"spring.kafka.retry.topic.attempts=4", "spring.kafka.retry.topic.delay=0")
.run(assertRetryTopicConfiguration(
(configuration) -> assertThat(configuration.getDestinationTopicProperties()).hasSize(3)
.extracting(DestinationTopic.Properties::delay)
.containsExactly(0L, 0L, 0L)));
}
private ContextConsumer<AssertableApplicationContext> assertRetryTopicConfiguration(
Consumer<RetryTopicConfiguration> configuration) {
return (context) -> {

View File

@ -190,21 +190,21 @@ class OtlpMetricsPropertiesConfigAdapterTests {
}
@Test
void serviceGroupOverridesApplicationGroup() {
void serviceNamespaceOverridesApplicationGroup() {
this.environment.setProperty("spring.application.group", "alpha");
this.openTelemetryProperties.setResourceAttributes(Map.of("service.group", "beta"));
assertThat(createAdapter().resourceAttributes()).containsEntry("service.group", "beta");
this.openTelemetryProperties.setResourceAttributes(Map.of("service.namespace", "beta"));
assertThat(createAdapter().resourceAttributes()).containsEntry("service.namespace", "beta");
}
@Test
void shouldUseApplicationGroupIfServiceGroupIsNotSet() {
void shouldUseApplicationGroupIfServiceNamspaceIsNotSet() {
this.environment.setProperty("spring.application.group", "alpha");
assertThat(createAdapter().resourceAttributes()).containsEntry("service.group", "alpha");
assertThat(createAdapter().resourceAttributes()).containsEntry("service.namespace", "alpha");
}
@Test
void shouldUseDefaultApplicationGroupIfApplicationGroupIsNotSet() {
assertThat(createAdapter().resourceAttributes()).doesNotContainKey("service.group");
assertThat(createAdapter().resourceAttributes()).doesNotContainKey("service.namespace");
}
private OtlpMetricsPropertiesConfigAdapter createAdapter() {

View File

@ -49,25 +49,6 @@ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClient
private int order = 0;
/**
* Create a new instance.
* @param connectionString the connection string
* @param uuidRepresentation the uuid representation
* @param ssl the ssl properties
* @param sslBundles the ssl bundles
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
* {@link #StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails, UuidRepresentation)}
*/
@Deprecated(forRemoval = true, since = "3.5.0")
public StandardMongoClientSettingsBuilderCustomizer(ConnectionString connectionString,
UuidRepresentation uuidRepresentation, MongoProperties.Ssl ssl, SslBundles sslBundles) {
this.connectionDetails = null;
this.connectionString = connectionString;
this.uuidRepresentation = uuidRepresentation;
this.ssl = ssl;
this.sslBundles = sslBundles;
}
public StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails connectionDetails,
UuidRepresentation uuidRepresentation) {
this.connectionString = null;

View File

@ -98,7 +98,6 @@ public class OpenTelemetryResourceAttributes {
}
});
attributes.computeIfAbsent("service.name", (key) -> getApplicationName());
attributes.computeIfAbsent("service.group", (key) -> getApplicationGroup());
attributes.computeIfAbsent("service.namespace", (key) -> getServiceNamespace());
attributes.forEach(consumer);
}
@ -107,17 +106,6 @@ public class OpenTelemetryResourceAttributes {
return this.environment.getProperty("spring.application.name", DEFAULT_SERVICE_NAME);
}
/**
* Returns the application group.
* @return the application group
* @deprecated since 3.5.0 for removal in 4.0.0
*/
@Deprecated(since = "3.5.0", forRemoval = true)
private String getApplicationGroup() {
String applicationGroup = this.environment.getProperty("spring.application.group");
return (StringUtils.hasLength(applicationGroup)) ? applicationGroup : null;
}
private String getServiceNamespace() {
return this.environment.getProperty("spring.application.group");
}

View File

@ -159,11 +159,10 @@ class OpenTelemetryResourceAttributesTests {
}
@Test
void springApplicationGroupNameShouldBeUsedAsDefaultServiceGroup() {
void springApplicationGroupNameShouldBeUsedAsDefaultServiceNamespace() {
this.environment.setProperty("spring.application.group", "spring-boot");
assertThat(getAttributes()).hasSize(3)
assertThat(getAttributes()).hasSize(2)
.containsEntry("service.name", "unknown_service")
.containsEntry("service.group", "spring-boot")
.containsEntry("service.namespace", "spring-boot");
}
@ -212,28 +211,26 @@ class OpenTelemetryResourceAttributesTests {
void resourceAttributesShouldTakePrecedenceOverApplicationGroupNameForPopulatingServiceNamespace() {
this.resourceAttributes.put("service.namespace", "spring-boot-app");
this.environment.setProperty("spring.application.group", "overridden");
assertThat(getAttributes()).hasSize(3)
assertThat(getAttributes()).hasSize(2)
.containsEntry("service.name", "unknown_service")
.containsEntry("service.group", "overridden")
.containsEntry("service.namespace", "spring-boot-app");
}
@Test
void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupName() {
this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.group=spring-boot");
this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.namespace=spring-boot");
this.environment.setProperty("spring.application.group", "spring-boot-app");
assertThat(getAttributes()).hasSize(3)
assertThat(getAttributes()).hasSize(2)
.containsEntry("service.name", "unknown_service")
.containsEntry("service.group", "spring-boot")
.containsEntry("service.namespace", "spring-boot-app");
.containsEntry("service.namespace", "spring-boot");
}
@Test
void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupNameForServiceNamespace() {
this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.namespace=spring-boot");
this.environment.setProperty("spring.application.group", "overridden");
assertThat(getAttributes()).hasSize(3)
.containsEntry("service.group", "overridden")
assertThat(getAttributes()).hasSize(2)
.containsEntry("service.name", "unknown_service")
.containsEntry("service.namespace", "spring-boot");
}

View File

@ -123,15 +123,6 @@ class OpenTelemetrySdkAutoConfigurationTests {
});
}
@Test
void whenHasApplicationGroupPropertyProvidesServiceGroupResourceAttribute() {
this.contextRunner.withPropertyValues("spring.application.group=my-group").run((context) -> {
Resource resource = context.getBean(Resource.class);
assertThat(resource.getAttributes().asMap())
.contains(entry(AttributeKey.stringKey("service.group"), "my-group"));
});
}
@Test
void whenHasApplicationGroupPropertyProvidesServiceNamespaceResourceAttribute() {
this.contextRunner.withPropertyValues("spring.application.group=my-group").run((context) -> {

View File

@ -446,19 +446,6 @@ public class RestTemplateBuilder {
this.defaultHeaders, this.customizers, this.requestCustomizers);
}
/**
* Sets the connection timeout on the underlying {@link ClientHttpRequestFactory}.
* @param connectTimeout the connection timeout
* @return a new builder instance.
* @since 2.1.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #connectTimeout(Duration)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public RestTemplateBuilder setConnectTimeout(Duration connectTimeout) {
return connectTimeout(connectTimeout);
}
/**
* Sets the connection timeout on the underlying {@link ClientHttpRequestFactory}.
* @param connectTimeout the connection timeout
@ -472,19 +459,6 @@ public class RestTemplateBuilder {
this.defaultHeaders, this.customizers, this.requestCustomizers);
}
/**
* Sets the read timeout on the underlying {@link ClientHttpRequestFactory}.
* @param readTimeout the read timeout
* @return a new builder instance.
* @since 2.1.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #readTimeout(Duration)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public RestTemplateBuilder setReadTimeout(Duration readTimeout) {
return readTimeout(readTimeout);
}
/**
* Sets the read timeout on the underlying {@link ClientHttpRequestFactory}.
* @param readTimeout the read timeout
@ -511,19 +485,6 @@ public class RestTemplateBuilder {
this.customizers, this.requestCustomizers);
}
/**
* Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}.
* @param sslBundle the SSL bundle
* @return a new builder instance
* @since 3.1.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #sslBundle(SslBundle)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public RestTemplateBuilder setSslBundle(SslBundle sslBundle) {
return sslBundle(sslBundle);
}
/**
* Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}.
* @param sslBundle the SSL bundle

View File

@ -47,15 +47,6 @@ public class SecurityProperties {
*/
public static final int BASIC_AUTH_ORDER = Ordered.LOWEST_PRECEDENCE - 5;
/**
* Order applied to the {@code WebSecurityCustomizer} that ignores standard static
* resource paths.
* @deprecated since 3.5.0 for removal in 4.0.0 since Spring Security no longer
* recommends using the {@code .ignoring()} method
*/
@Deprecated(since = "3.5.0", forRemoval = true)
public static final int IGNORED_ORDER = Ordered.HIGHEST_PRECEDENCE;
/**
* Default order of Spring Security's Filter in the servlet container (i.e. amongst
* other filters registered with the container). There is no connection between this

View File

@ -35,6 +35,8 @@ dependencies {
api(project(":spring-boot-project:spring-boot"))
api(project(":spring-boot-project:spring-boot-autoconfigure"))
api(project(":spring-boot-project:spring-boot-test"))
compileOnly("org.mockito:mockito-core")
dockerTestImplementation(project(":spring-boot-project:spring-boot-data-mongodb"))
dockerTestImplementation(project(":spring-boot-project:spring-boot-docker-compose"))

View File

@ -1,45 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ApplicationContextFailureProcessor;
/**
* An {@link ApplicationContextFailureProcessor} that prints the
* {@link ConditionEvaluationReport} when the context cannot be prepared.
*
* @author Phillip Webb
* @author Scott Frederick
* @since 3.0.0
* @deprecated in 3.2.11 for removal in 4.0.0
*/
@Deprecated(since = "3.2.11", forRemoval = true)
public class ConditionReportApplicationContextFailureProcessor implements ApplicationContextFailureProcessor {
@Override
public void processLoadFailure(ApplicationContext context, Throwable exception) {
if (context instanceof ConfigurableApplicationContext configurableContext) {
ConditionEvaluationReport report = ConditionEvaluationReport.get(configurableContext.getBeanFactory());
System.err.println(new ConditionEvaluationReportMessage(report));
}
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.autoconfigure;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ConditionReportApplicationContextFailureProcessor}.
*
* @author Phillip Webb
* @author Scott Frederick
* @deprecated since 3.2.11 for removal in 4.0.0
*/
@ExtendWith(OutputCaptureExtension.class)
@Deprecated(since = "3.2.11", forRemoval = true)
@SuppressWarnings("removal")
class ConditionReportApplicationContextFailureProcessorTests {
@Test
void loadFailureShouldPrintReport(CapturedOutput output) {
SpringApplication application = new SpringApplication(TestConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
ConfigurableApplicationContext applicationContext = application.run();
ConditionReportApplicationContextFailureProcessor processor = new ConditionReportApplicationContextFailureProcessor();
processor.processLoadFailure(applicationContext, new IllegalStateException());
assertThat(output).contains("CONDITIONS EVALUATION REPORT")
.contains("Positive matches")
.contains("Negative matches");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(JacksonAutoConfiguration.class)
static class TestConfig {
}
}

View File

@ -110,26 +110,10 @@ import org.springframework.util.CollectionUtils;
*/
public abstract class AbstractApplicationContextRunner<SELF extends AbstractApplicationContextRunner<SELF, C, A>, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider<C>> {
private static final Class<?>[] NO_ADDITIONAL_CONTEXT_INTERFACES = {};
private final RunnerConfiguration<C> runnerConfiguration;
private final Function<RunnerConfiguration<C>, SELF> instanceFactory;
/**
* Create a new {@link AbstractApplicationContextRunner} instance.
* @param contextFactory the factory used to create the actual context
* @param instanceFactory the factory used to create new instance of the runner
* @since 2.6.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link #AbstractApplicationContextRunner(Function, Supplier, Class...)}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
protected AbstractApplicationContextRunner(Supplier<C> contextFactory,
Function<RunnerConfiguration<C>, SELF> instanceFactory) {
this(instanceFactory, contextFactory, NO_ADDITIONAL_CONTEXT_INTERFACES);
}
/**
* Create a new {@link AbstractApplicationContextRunner} instance.
* @param instanceFactory the factory used to create new instance of the runner

View File

@ -1,108 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.springframework.util.ObjectUtils;
/**
* Base class for {@link MockDefinition} and {@link SpyDefinition}.
*
* @author Phillip Webb
* @see DefinitionsParser
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
abstract class Definition {
private static final int MULTIPLIER = 31;
private final String name;
private final MockReset reset;
private final boolean proxyTargetAware;
private final QualifierDefinition qualifier;
Definition(String name, MockReset reset, boolean proxyTargetAware, QualifierDefinition qualifier) {
this.name = name;
this.reset = (reset != null) ? reset : MockReset.AFTER;
this.proxyTargetAware = proxyTargetAware;
this.qualifier = qualifier;
}
/**
* Return the name for bean.
* @return the name or {@code null}
*/
String getName() {
return this.name;
}
/**
* Return the mock reset mode.
* @return the reset mode
*/
MockReset getReset() {
return this.reset;
}
/**
* Return if AOP advised beans should be proxy target aware.
* @return if proxy target aware
*/
boolean isProxyTargetAware() {
return this.proxyTargetAware;
}
/**
* Return the qualifier or {@code null}.
* @return the qualifier
*/
QualifierDefinition getQualifier() {
return this.qualifier;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !getClass().isAssignableFrom(obj.getClass())) {
return false;
}
Definition other = (Definition) obj;
boolean result = true;
result = result && ObjectUtils.nullSafeEquals(this.name, other.name);
result = result && ObjectUtils.nullSafeEquals(this.reset, other.reset);
result = result && ObjectUtils.nullSafeEquals(this.proxyTargetAware, other.proxyTargetAware);
result = result && ObjectUtils.nullSafeEquals(this.qualifier, other.qualifier);
return result;
}
@Override
public int hashCode() {
int result = 1;
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.name);
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.reset);
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.proxyTargetAware);
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.qualifier);
return result;
}
}

View File

@ -1,136 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.TypeVariable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Parser to create {@link MockDefinition} and {@link SpyDefinition} instances from
* {@link MockBean @MockBean} and {@link SpyBean @SpyBean} annotations declared on or in a
* class.
*
* @author Phillip Webb
* @author Stephane Nicoll
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class DefinitionsParser {
private final Set<Definition> definitions;
private final Map<Definition, Field> definitionFields;
DefinitionsParser() {
this(Collections.emptySet());
}
DefinitionsParser(Collection<? extends Definition> existing) {
this.definitions = new LinkedHashSet<>();
this.definitionFields = new LinkedHashMap<>();
if (existing != null) {
this.definitions.addAll(existing);
}
}
void parse(Class<?> source) {
parseElement(source, null);
ReflectionUtils.doWithFields(source, (element) -> parseElement(element, source));
}
private void parseElement(AnnotatedElement element, Class<?> source) {
MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.SUPERCLASS);
annotations.stream(MockBean.class)
.map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseMockBeanAnnotation(annotation, element, source));
annotations.stream(SpyBean.class)
.map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseSpyBeanAnnotation(annotation, element, source));
}
private void parseMockBeanAnnotation(MockBean annotation, AnnotatedElement element, Class<?> source) {
Set<ResolvableType> typesToMock = getOrDeduceTypes(element, annotation.value(), source);
Assert.state(!typesToMock.isEmpty(), () -> "Unable to deduce type to mock from " + element);
if (StringUtils.hasLength(annotation.name())) {
Assert.state(typesToMock.size() == 1, "The name attribute can only be used when mocking a single class");
}
for (ResolvableType typeToMock : typesToMock) {
MockDefinition definition = new MockDefinition(annotation.name(), typeToMock, annotation.extraInterfaces(),
annotation.answer(), annotation.serializable(), annotation.reset(),
QualifierDefinition.forElement(element));
addDefinition(element, definition, "mock");
}
}
private void parseSpyBeanAnnotation(SpyBean annotation, AnnotatedElement element, Class<?> source) {
Set<ResolvableType> typesToSpy = getOrDeduceTypes(element, annotation.value(), source);
Assert.state(!typesToSpy.isEmpty(), () -> "Unable to deduce type to spy from " + element);
if (StringUtils.hasLength(annotation.name())) {
Assert.state(typesToSpy.size() == 1, "The name attribute can only be used when spying a single class");
}
for (ResolvableType typeToSpy : typesToSpy) {
SpyDefinition definition = new SpyDefinition(annotation.name(), typeToSpy, annotation.reset(),
annotation.proxyTargetAware(), QualifierDefinition.forElement(element));
addDefinition(element, definition, "spy");
}
}
private void addDefinition(AnnotatedElement element, Definition definition, String type) {
boolean isNewDefinition = this.definitions.add(definition);
Assert.state(isNewDefinition, () -> "Duplicate " + type + " definition " + definition);
if (element instanceof Field field) {
this.definitionFields.put(definition, field);
}
}
private Set<ResolvableType> getOrDeduceTypes(AnnotatedElement element, Class<?>[] value, Class<?> source) {
Set<ResolvableType> types = new LinkedHashSet<>();
for (Class<?> type : value) {
types.add(ResolvableType.forClass(type));
}
if (types.isEmpty() && element instanceof Field field) {
types.add((field.getGenericType() instanceof TypeVariable) ? ResolvableType.forField(field, source)
: ResolvableType.forField(field));
}
return types;
}
Set<Definition> getDefinitions() {
return Collections.unmodifiableSet(this.definitions);
}
Field getField(Definition definition) {
return this.definitionFields.get(definition);
}
}

View File

@ -1,163 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.MockSettings;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Annotation that can be used to add mocks to a Spring {@link ApplicationContext}. Can be
* used as a class level annotation or on fields in either {@code @Configuration} classes,
* or test classes that are {@link RunWith @RunWith} the {@link SpringRunner}.
* <p>
* Mocks can be registered by type or by {@link #name() bean name}. When registered by
* type, any existing single bean of a matching type (including subclasses) in the context
* will be replaced by the mock. When registered by name, an existing bean can be
* specifically targeted for replacement by a mock. In either case, if no existing bean is
* defined a new one will be added. Dependencies that are known to the application context
* but are not beans (such as those
* {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object)
* registered directly}) will not be found and a mocked bean will be added to the context
* alongside the existing dependency.
* <p>
* When {@code @MockBean} is used on a field, as well as being registered in the
* application context, the mock will also be injected into the field. Typical usage might
* be: <pre class="code">
* &#064;RunWith(SpringRunner.class)
* public class ExampleTests {
*
* &#064;MockBean
* private ExampleService service;
*
* &#064;Autowired
* private UserOfService userOfService;
*
* &#064;Test
* public void testUserOfService() {
* given(this.service.greet()).willReturn("Hello");
* String actual = this.userOfService.makeUse();
* assertEquals("Was: Hello", actual);
* }
*
* &#064;Configuration
* &#064;Import(UserOfService.class) // A &#064;Component injected with ExampleService
* static class Config {
* }
*
*
* }
* </pre> If there is more than one bean of the requested type, qualifier metadata must be
* specified at field level: <pre class="code">
* &#064;RunWith(SpringRunner.class)
* public class ExampleTests {
*
* &#064;MockBean
* &#064;Qualifier("example")
* private ExampleService service;
*
* ...
* }
* </pre>
* <p>
* This annotation is {@code @Repeatable} and may be specified multiple times when working
* with Java 8 or contained within an {@link MockBeans @MockBeans} annotation.
*
* @author Phillip Webb
* @since 1.4.0
* @see MockitoPostProcessor
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockitoBean}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(MockBeans.class)
public @interface MockBean {
/**
* The name of the bean to register or replace. If not specified the name will either
* be generated or, if the mock replaces an existing bean, the existing name will be
* used.
* @return the name of the bean
*/
String name() default "";
/**
* The classes to mock. This is an alias of {@link #classes()} which can be used for
* brevity if no other attributes are defined. See {@link #classes()} for details.
* @return the classes to mock
*/
@AliasFor("classes")
Class<?>[] value() default {};
/**
* The classes to mock. Each class specified here will result in a mock being created
* and registered with the application context. Classes can be omitted when the
* annotation is used on a field.
* <p>
* When {@code @MockBean} also defines a {@code name} this attribute can only contain
* a single value.
* <p>
* If this is the only specified attribute consider using the {@code value} alias
* instead.
* @return the classes to mock
*/
@AliasFor("value")
Class<?>[] classes() default {};
/**
* Any extra interfaces that should also be declared on the mock. See
* {@link MockSettings#extraInterfaces(Class...)} for details.
* @return any extra interfaces
*/
Class<?>[] extraInterfaces() default {};
/**
* The {@link Answers} type to use on the mock.
* @return the answer type
*/
Answers answer() default Answers.RETURNS_DEFAULTS;
/**
* If the generated mock is serializable. See {@link MockSettings#serializable()} for
* details.
* @return if the mock is serializable
*/
boolean serializable() default false;
/**
* The reset mode to apply to the mock bean. The default is {@link MockReset#AFTER}
* meaning that mocks are automatically reset after each test method is invoked.
* @return the reset mode
*/
MockReset reset() default MockReset.AFTER;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.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;
/**
* Container annotation that aggregates several {@link MockBean @MockBean} annotations.
* <p>
* Can be used natively, declaring several nested {@link MockBean @MockBean} annotations.
* Can also be used in conjunction with Java 8's support for <em>repeatable
* annotations</em>, where {@link MockBean @MockBean} can simply be declared several times
* on the same {@linkplain ElementType#TYPE type}, implicitly generating this container
* annotation.
*
* @author Phillip Webb
* @since 1.4.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockitoBean}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface MockBeans {
/**
* Return the contained {@link MockBean @MockBean} annotations.
* @return the mock beans
*/
MockBean[] value();
}

View File

@ -1,164 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.mockito.Answers;
import org.mockito.MockSettings;
import org.springframework.core.ResolvableType;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import static org.mockito.Mockito.mock;
/**
* A complete definition that can be used to create a Mockito mock.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class MockDefinition extends Definition {
private static final int MULTIPLIER = 31;
private final ResolvableType typeToMock;
private final Set<Class<?>> extraInterfaces;
private final Answers answer;
private final boolean serializable;
MockDefinition(String name, ResolvableType typeToMock, Class<?>[] extraInterfaces, Answers answer,
boolean serializable, MockReset reset, QualifierDefinition qualifier) {
super(name, reset, false, qualifier);
Assert.notNull(typeToMock, "'typeToMock' must not be null");
this.typeToMock = typeToMock;
this.extraInterfaces = asClassSet(extraInterfaces);
this.answer = (answer != null) ? answer : Answers.RETURNS_DEFAULTS;
this.serializable = serializable;
}
private Set<Class<?>> asClassSet(Class<?>[] classes) {
Set<Class<?>> classSet = new LinkedHashSet<>();
if (classes != null) {
classSet.addAll(Arrays.asList(classes));
}
return Collections.unmodifiableSet(classSet);
}
/**
* Return the type that should be mocked.
* @return the type to mock; never {@code null}
*/
ResolvableType getTypeToMock() {
return this.typeToMock;
}
/**
* Return the extra interfaces.
* @return the extra interfaces or an empty set
*/
Set<Class<?>> getExtraInterfaces() {
return this.extraInterfaces;
}
/**
* Return the answers mode.
* @return the answers mode; never {@code null}
*/
Answers getAnswer() {
return this.answer;
}
/**
* Return if the mock is serializable.
* @return if the mock is serializable
*/
boolean isSerializable() {
return this.serializable;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != getClass()) {
return false;
}
MockDefinition other = (MockDefinition) obj;
boolean result = super.equals(obj);
result = result && ObjectUtils.nullSafeEquals(this.typeToMock, other.typeToMock);
result = result && ObjectUtils.nullSafeEquals(this.extraInterfaces, other.extraInterfaces);
result = result && ObjectUtils.nullSafeEquals(this.answer, other.answer);
result = result && this.serializable == other.serializable;
return result;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.typeToMock);
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.extraInterfaces);
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.answer);
result = MULTIPLIER * result + Boolean.hashCode(this.serializable);
return result;
}
@Override
public String toString() {
return new ToStringCreator(this).append("name", getName())
.append("typeToMock", this.typeToMock)
.append("extraInterfaces", this.extraInterfaces)
.append("answer", this.answer)
.append("serializable", this.serializable)
.append("reset", getReset())
.toString();
}
<T> T createMock() {
return createMock(getName());
}
@SuppressWarnings("unchecked")
<T> T createMock(String name) {
MockSettings settings = MockReset.withSettings(getReset());
if (StringUtils.hasLength(name)) {
settings.name(name);
}
if (!this.extraInterfaces.isEmpty()) {
settings.extraInterfaces(ClassUtils.toClassArray(this.extraInterfaces));
}
settings.defaultAnswer(this.answer);
if (this.serializable) {
settings.serializable();
}
return (T) mock(this.typeToMock.resolve(), settings);
}
}

View File

@ -1,142 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.List;
import org.mockito.MockSettings;
import org.mockito.MockingDetails;
import org.mockito.Mockito;
import org.mockito.listeners.InvocationListener;
import org.mockito.listeners.MethodInvocationReport;
import org.mockito.mock.MockCreationSettings;
import org.springframework.util.Assert;
/**
* Reset strategy used on a mock bean. Usually applied to a mock through the
* {@link MockBean @MockBean} annotation but can also be directly applied to any mock in
* the {@code ApplicationContext} using the static methods.
*
* @author Phillip Webb
* @since 1.4.0
* @see ResetMocksTestExecutionListener
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockReset}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public enum MockReset {
/**
* Reset the mock before the test method runs.
*/
BEFORE,
/**
* Reset the mock after the test method runs.
*/
AFTER,
/**
* Don't reset the mock.
*/
NONE;
/**
* Create {@link MockSettings settings} to be used with mocks where reset should occur
* before each test method runs.
* @return mock settings
*/
public static MockSettings before() {
return withSettings(BEFORE);
}
/**
* Create {@link MockSettings settings} to be used with mocks where reset should occur
* after each test method runs.
* @return mock settings
*/
public static MockSettings after() {
return withSettings(AFTER);
}
/**
* Create {@link MockSettings settings} to be used with mocks where a specific reset
* should occur.
* @param reset the reset type
* @return mock settings
*/
public static MockSettings withSettings(MockReset reset) {
return apply(reset, Mockito.withSettings());
}
/**
* Apply {@link MockReset} to existing {@link MockSettings settings}.
* @param reset the reset type
* @param settings the settings
* @return the configured settings
*/
public static MockSettings apply(MockReset reset, MockSettings settings) {
Assert.notNull(settings, "'settings' must not be null");
if (reset != null && reset != NONE) {
settings.invocationListeners(new ResetInvocationListener(reset));
}
return settings;
}
/**
* Get the {@link MockReset} associated with the given mock.
* @param mock the source mock
* @return the reset type (never {@code null})
*/
static MockReset get(Object mock) {
MockReset reset = MockReset.NONE;
MockingDetails mockingDetails = Mockito.mockingDetails(mock);
if (mockingDetails.isMock()) {
MockCreationSettings<?> settings = mockingDetails.getMockCreationSettings();
List<InvocationListener> listeners = settings.getInvocationListeners();
for (Object listener : listeners) {
if (listener instanceof ResetInvocationListener resetInvocationListener) {
reset = resetInvocationListener.getReset();
}
}
}
return reset;
}
/**
* Dummy {@link InvocationListener} used to hold the {@link MockReset} value.
*/
private static class ResetInvocationListener implements InvocationListener {
private final MockReset reset;
ResetInvocationListener(MockReset reset) {
this.reset = reset;
}
MockReset getReset() {
return this.reset;
}
@Override
public void reportInvocation(MethodInvocationReport methodInvocationReport) {
}
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Beans created using Mockito.
*
* @author Andy Wilkinson
*/
class MockitoBeans implements Iterable<Object> {
private final List<Object> beans = new ArrayList<>();
void add(Object bean) {
this.beans.add(bean);
}
@Override
public Iterator<Object> iterator() {
return this.beans.iterator();
}
}

View File

@ -1,68 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
/**
* A {@link ContextCustomizer} to add Mockito support.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class MockitoContextCustomizer implements ContextCustomizer {
private final Set<Definition> definitions;
MockitoContextCustomizer(Set<? extends Definition> definitions) {
this.definitions = new LinkedHashSet<>(definitions);
}
@Override
public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedContextConfiguration) {
if (context instanceof BeanDefinitionRegistry registry) {
MockitoPostProcessor.register(registry, this.definitions);
}
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != getClass()) {
return false;
}
MockitoContextCustomizer other = (MockitoContextCustomizer) obj;
return this.definitions.equals(other.definitions);
}
@Override
public int hashCode() {
return this.definitions.hashCode();
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.List;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.TestContextAnnotationUtils;
/**
* A {@link ContextCustomizerFactory} to add Mockito support.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class MockitoContextCustomizerFactory implements ContextCustomizerFactory {
@Override
public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
// We gather the explicit mock definitions here since they form part of the
// MergedContextConfiguration key. Different mocks need to have a different key.
DefinitionsParser parser = new DefinitionsParser();
parseDefinitions(testClass, parser);
return new MockitoContextCustomizer(parser.getDefinitions());
}
private void parseDefinitions(Class<?> testClass, DefinitionsParser parser) {
parser.parse(testClass);
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
parseDefinitions(testClass.getEnclosingClass(), parser);
}
}
}

View File

@ -1,494 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Conventions;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.ResolvableType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* A {@link BeanFactoryPostProcessor} used to register and inject
* {@link MockBean @MockBeans} with the {@link ApplicationContext}. An initial set of
* definitions can be passed to the processor with additional definitions being
* automatically created from {@code @Configuration} classes that use
* {@link MockBean @MockBean}.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Andreas Neiser
* @since 1.4.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's
* {@link MockitoBean} and {@link MockitoSpyBean} support
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0")
public class MockitoPostProcessor implements InstantiationAwareBeanPostProcessor, BeanClassLoaderAware,
BeanFactoryAware, BeanFactoryPostProcessor, Ordered {
private static final String BEAN_NAME = MockitoPostProcessor.class.getName();
private static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions
.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
private final Set<Definition> definitions;
private ClassLoader classLoader;
private BeanFactory beanFactory;
private final MockitoBeans mockitoBeans = new MockitoBeans();
private final Map<Definition, String> beanNameRegistry = new HashMap<>();
private final Map<Field, String> fieldRegistry = new HashMap<>();
private final Map<String, SpyDefinition> spies = new HashMap<>();
/**
* Create a new {@link MockitoPostProcessor} instance with the given initial
* definitions.
* @param definitions the initial definitions
*/
public MockitoPostProcessor(Set<Definition> definitions) {
this.definitions = definitions;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
Assert.isTrue(beanFactory instanceof ConfigurableListableBeanFactory,
"'beanFactory' must be a ConfigurableListableBeanFactory");
this.beanFactory = beanFactory;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Assert.isTrue(beanFactory instanceof BeanDefinitionRegistry, "'beanFactory' must be a BeanDefinitionRegistry");
postProcessBeanFactory(beanFactory, (BeanDefinitionRegistry) beanFactory);
}
private void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) {
beanFactory.registerSingleton(MockitoBeans.class.getName(), this.mockitoBeans);
DefinitionsParser parser = new DefinitionsParser(this.definitions);
for (Class<?> configurationClass : getConfigurationClasses(beanFactory)) {
parser.parse(configurationClass);
}
Set<Definition> definitions = parser.getDefinitions();
for (Definition definition : definitions) {
Field field = parser.getField(definition);
register(beanFactory, registry, definition, field);
}
}
private Set<Class<?>> getConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Set<Class<?>> configurationClasses = new LinkedHashSet<>();
for (BeanDefinition beanDefinition : getConfigurationBeanDefinitions(beanFactory).values()) {
configurationClasses.add(ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), this.classLoader));
}
return configurationClasses;
}
private Map<String, BeanDefinition> getConfigurationBeanDefinitions(ConfigurableListableBeanFactory beanFactory) {
Map<String, BeanDefinition> definitions = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
if (definition.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE) != null) {
definitions.put(beanName, definition);
}
}
return definitions;
}
private void register(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
Definition definition, Field field) {
if (definition instanceof MockDefinition mockDefinition) {
registerMock(beanFactory, registry, mockDefinition, field);
}
else if (definition instanceof SpyDefinition spyDefinition) {
registerSpy(beanFactory, registry, spyDefinition, field);
}
}
private void registerMock(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
MockDefinition definition, Field field) {
RootBeanDefinition beanDefinition = createBeanDefinition(definition);
String beanName = getBeanName(beanFactory, registry, definition, beanDefinition);
String transformedBeanName = BeanFactoryUtils.transformedBeanName(beanName);
if (registry.containsBeanDefinition(transformedBeanName)) {
BeanDefinition existing = registry.getBeanDefinition(transformedBeanName);
copyBeanDefinitionDetails(existing, beanDefinition);
registry.removeBeanDefinition(transformedBeanName);
}
registry.registerBeanDefinition(transformedBeanName, beanDefinition);
Object mock = definition.createMock(beanName + " bean");
beanFactory.registerSingleton(transformedBeanName, mock);
this.mockitoBeans.add(mock);
this.beanNameRegistry.put(definition, beanName);
if (field != null) {
this.fieldRegistry.put(field, beanName);
}
}
private RootBeanDefinition createBeanDefinition(MockDefinition mockDefinition) {
RootBeanDefinition definition = new RootBeanDefinition(mockDefinition.getTypeToMock().resolve());
definition.setTargetType(mockDefinition.getTypeToMock());
if (mockDefinition.getQualifier() != null) {
mockDefinition.getQualifier().applyTo(definition);
}
return definition;
}
private String getBeanName(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
MockDefinition mockDefinition, RootBeanDefinition beanDefinition) {
if (StringUtils.hasLength(mockDefinition.getName())) {
return mockDefinition.getName();
}
Set<String> existingBeans = getExistingBeans(beanFactory, mockDefinition.getTypeToMock(),
mockDefinition.getQualifier());
if (existingBeans.isEmpty()) {
return MockitoPostProcessor.beanNameGenerator.generateBeanName(beanDefinition, registry);
}
if (existingBeans.size() == 1) {
return existingBeans.iterator().next();
}
String primaryCandidate = determinePrimaryCandidate(registry, existingBeans, mockDefinition.getTypeToMock());
if (primaryCandidate != null) {
return primaryCandidate;
}
throw new IllegalStateException("Unable to register mock bean " + mockDefinition.getTypeToMock()
+ " expected a single matching bean to replace but found " + existingBeans);
}
private void copyBeanDefinitionDetails(BeanDefinition from, RootBeanDefinition to) {
to.setPrimary(from.isPrimary());
}
private void registerSpy(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
SpyDefinition spyDefinition, Field field) {
Set<String> existingBeans = getExistingBeans(beanFactory, spyDefinition.getTypeToSpy(),
spyDefinition.getQualifier());
if (ObjectUtils.isEmpty(existingBeans)) {
createSpy(registry, spyDefinition, field);
}
else {
registerSpies(registry, spyDefinition, field, existingBeans);
}
}
private Set<String> getExistingBeans(ConfigurableListableBeanFactory beanFactory, ResolvableType type,
QualifierDefinition qualifier) {
Set<String> candidates = new TreeSet<>();
for (String candidate : getExistingBeans(beanFactory, type)) {
if (qualifier == null || qualifier.matches(beanFactory, candidate)) {
candidates.add(candidate);
}
}
return candidates;
}
private Set<String> getExistingBeans(ConfigurableListableBeanFactory beanFactory, ResolvableType resolvableType) {
Set<String> beans = new LinkedHashSet<>(
Arrays.asList(beanFactory.getBeanNamesForType(resolvableType, true, false)));
Class<?> type = resolvableType.resolve(Object.class);
for (String beanName : beanFactory.getBeanNamesForType(FactoryBean.class, true, false)) {
beanName = BeanFactoryUtils.transformedBeanName(beanName);
Class<?> producedType = beanFactory.getType(beanName, false);
if (type.equals(producedType)) {
beans.add(beanName);
}
}
beans.removeIf(this::isScopedTarget);
return beans;
}
private boolean isScopedTarget(String beanName) {
try {
return ScopedProxyUtils.isScopedTarget(beanName);
}
catch (Throwable ex) {
return false;
}
}
private void createSpy(BeanDefinitionRegistry registry, SpyDefinition spyDefinition, Field field) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(spyDefinition.getTypeToSpy().resolve());
String beanName = MockitoPostProcessor.beanNameGenerator.generateBeanName(beanDefinition, registry);
registry.registerBeanDefinition(beanName, beanDefinition);
registerSpy(spyDefinition, field, beanName);
}
private void registerSpies(BeanDefinitionRegistry registry, SpyDefinition spyDefinition, Field field,
Collection<String> existingBeans) {
try {
String beanName = determineBeanName(existingBeans, spyDefinition, registry);
registerSpy(spyDefinition, field, beanName);
}
catch (RuntimeException ex) {
throw new IllegalStateException("Unable to register spy bean " + spyDefinition.getTypeToSpy(), ex);
}
}
private String determineBeanName(Collection<String> existingBeans, SpyDefinition definition,
BeanDefinitionRegistry registry) {
if (StringUtils.hasText(definition.getName())) {
return definition.getName();
}
if (existingBeans.size() == 1) {
return existingBeans.iterator().next();
}
return determinePrimaryCandidate(registry, existingBeans, definition.getTypeToSpy());
}
private String determinePrimaryCandidate(BeanDefinitionRegistry registry, Collection<String> candidateBeanNames,
ResolvableType type) {
String primaryBeanName = null;
for (String candidateBeanName : candidateBeanNames) {
BeanDefinition beanDefinition = registry.getBeanDefinition(candidateBeanName);
if (beanDefinition.isPrimary()) {
if (primaryBeanName != null) {
throw new NoUniqueBeanDefinitionException(type.resolve(), candidateBeanNames.size(),
"more than one 'primary' bean found among candidates: "
+ Collections.singletonList(candidateBeanNames));
}
primaryBeanName = candidateBeanName;
}
}
return primaryBeanName;
}
private void registerSpy(SpyDefinition definition, Field field, String beanName) {
this.spies.put(beanName, definition);
this.beanNameRegistry.put(definition, beanName);
if (field != null) {
this.fieldRegistry.put(field, beanName);
}
}
protected final Object createSpyIfNecessary(Object bean, String beanName) throws BeansException {
SpyDefinition definition = this.spies.get(beanName);
if (definition != null) {
bean = definition.createSpy(beanName, bean);
this.mockitoBeans.add(bean);
}
return bean;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), (field) -> postProcessField(bean, field));
return pvs;
}
private void postProcessField(Object bean, Field field) {
String beanName = this.fieldRegistry.get(field);
if (StringUtils.hasText(beanName)) {
inject(field, bean, beanName);
}
}
void inject(Field field, Object target, Definition definition) {
String beanName = this.beanNameRegistry.get(definition);
Assert.state(StringUtils.hasLength(beanName), () -> "No bean found for definition " + definition);
inject(field, target, beanName);
}
private void inject(Field field, Object target, String beanName) {
try {
field.setAccessible(true);
Object existingValue = ReflectionUtils.getField(field, target);
Object bean = this.beanFactory.getBean(beanName, field.getType());
if (existingValue == bean) {
return;
}
Assert.state(existingValue == null, () -> "The existing value '" + existingValue + "' of field '" + field
+ "' is not the same as the new value '" + bean + "'");
ReflectionUtils.setField(field, target, bean);
}
catch (Throwable ex) {
throw new BeanCreationException("Could not inject field: " + field, ex);
}
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 10;
}
/**
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
* using the {@link SpringRunner} as registration is automatic.
* @param registry the bean definition registry
*/
public static void register(BeanDefinitionRegistry registry) {
register(registry, null);
}
/**
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
* using the {@link SpringRunner} as registration is automatic.
* @param registry the bean definition registry
* @param definitions the initial mock/spy definitions
*/
public static void register(BeanDefinitionRegistry registry, Set<Definition> definitions) {
register(registry, MockitoPostProcessor.class, definitions);
}
/**
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
* using the {@link SpringRunner} as registration is automatic.
* @param registry the bean definition registry
* @param postProcessor the post processor class to register
* @param definitions the initial mock/spy definitions
*/
@SuppressWarnings("unchecked")
public static void register(BeanDefinitionRegistry registry, Class<? extends MockitoPostProcessor> postProcessor,
Set<Definition> definitions) {
SpyPostProcessor.register(registry);
BeanDefinition definition = getOrAddBeanDefinition(registry, postProcessor);
ValueHolder constructorArg = definition.getConstructorArgumentValues().getIndexedArgumentValue(0, Set.class);
Set<Definition> existing = (Set<Definition>) constructorArg.getValue();
if (definitions != null) {
existing.addAll(definitions);
}
}
private static BeanDefinition getOrAddBeanDefinition(BeanDefinitionRegistry registry,
Class<? extends MockitoPostProcessor> postProcessor) {
if (!registry.containsBeanDefinition(BEAN_NAME)) {
RootBeanDefinition definition = new RootBeanDefinition(postProcessor);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
constructorArguments.addIndexedArgumentValue(0, new LinkedHashSet<>());
registry.registerBeanDefinition(BEAN_NAME, definition);
return definition;
}
return registry.getBeanDefinition(BEAN_NAME);
}
/**
* {@link BeanPostProcessor} to handle {@link SpyBean} definitions. Registered as a
* separate processor so that it can be ordered above AOP post processors.
*/
static class SpyPostProcessor implements SmartInstantiationAwareBeanPostProcessor, PriorityOrdered {
private static final String BEAN_NAME = SpyPostProcessor.class.getName();
private final Map<String, Object> earlySpyReferences = new ConcurrentHashMap<>(16);
private final MockitoPostProcessor mockitoPostProcessor;
SpyPostProcessor(MockitoPostProcessor mockitoPostProcessor) {
this.mockitoPostProcessor = mockitoPostProcessor;
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
if (bean instanceof FactoryBean) {
return bean;
}
this.earlySpyReferences.put(getCacheKey(bean, beanName), bean);
return this.mockitoPostProcessor.createSpyIfNecessary(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FactoryBean) {
return bean;
}
if (this.earlySpyReferences.remove(getCacheKey(bean, beanName)) != bean) {
return this.mockitoPostProcessor.createSpyIfNecessary(bean, beanName);
}
return bean;
}
private String getCacheKey(Object bean, String beanName) {
return StringUtils.hasLength(beanName) ? beanName : bean.getClass().getName();
}
static void register(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(BEAN_NAME)) {
RootBeanDefinition definition = new RootBeanDefinition(SpyPostProcessor.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
constructorArguments.addIndexedArgumentValue(0,
new RuntimeBeanReference(MockitoPostProcessor.BEAN_NAME));
registry.registerBeanDefinition(BEAN_NAME, definition);
}
}
}
}

View File

@ -1,177 +0,0 @@
/*
* Copyright 2012-present 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.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.bean.override.mockito.MockitoBean;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
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.
* <p>
* To use the automatic reset support of {@code @MockBean} and {@code @SpyBean}, configure
* {@link ResetMocksTestExecutionListener} as well.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Moritz Halbritter
* @since 1.4.2
* @see ResetMocksTestExecutionListener
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's support for
* {@link MockitoBean} and {@link MockitoSpyBean}.
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
public class MockitoTestExecutionListener extends AbstractTestExecutionListener {
private static final String MOCKS_ATTRIBUTE_NAME = MockitoTestExecutionListener.class.getName() + ".mocks";
@Override
public final int getOrder() {
return 1950;
}
@Override
public void prepareTestInstance(TestContext testContext) throws Exception {
closeMocks(testContext);
initMocks(testContext);
injectFields(testContext);
}
@Override
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));
}
private void reinjectFields(final TestContext testContext) {
postProcessFields(testContext, (mockitoField, postProcessor) -> {
ReflectionUtils.makeAccessible(mockitoField.field);
ReflectionUtils.setField(mockitoField.field, testContext.getTestInstance(), null);
postProcessor.inject(mockitoField.field, mockitoField.target, mockitoField.definition);
});
}
private void postProcessFields(TestContext testContext, BiConsumer<MockitoField, MockitoPostProcessor> consumer) {
DefinitionsParser parser = new DefinitionsParser();
parser.parse(testContext.getTestClass());
if (!parser.getDefinitions().isEmpty()) {
MockitoPostProcessor postProcessor = testContext.getApplicationContext()
.getBean(MockitoPostProcessor.class);
for (Definition definition : parser.getDefinitions()) {
Field field = parser.getField(definition);
if (field != null) {
consumer.accept(new MockitoField(field, testContext.getTestInstance(), definition), postProcessor);
}
}
}
}
/**
* {@link FieldCallback} to collect Mockito annotations.
*/
private static final class MockitoAnnotationCollection implements FieldCallback {
private final Set<Annotation> 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;
private final Object target;
private final Definition definition;
private MockitoField(Field field, Object instance, Definition definition) {
this.field = field;
this.target = instance;
this.definition = definition;
}
}
}

View File

@ -1,113 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.annotation.MergedAnnotations;
/**
* Definition of a Spring {@link Qualifier @Qualifier}.
*
* @author Phillip Webb
* @author Stephane Nicoll
* @see Definition
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class QualifierDefinition {
private final Field field;
private final DependencyDescriptor descriptor;
private final Set<Annotation> annotations;
QualifierDefinition(Field field, Set<Annotation> annotations) {
// We can't use the field or descriptor as part of the context key
// but we can assume that if two fields have the same qualifiers then
// it's safe for Spring to use either for qualifier logic
this.field = field;
this.descriptor = new DependencyDescriptor(field, true);
this.annotations = annotations;
}
boolean matches(ConfigurableListableBeanFactory beanFactory, String beanName) {
return beanFactory.isAutowireCandidate(beanName, this.descriptor);
}
void applyTo(RootBeanDefinition definition) {
definition.setQualifiedElement(this.field);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !getClass().isAssignableFrom(obj.getClass())) {
return false;
}
QualifierDefinition other = (QualifierDefinition) obj;
return this.annotations.equals(other.annotations);
}
@Override
public int hashCode() {
return this.annotations.hashCode();
}
static QualifierDefinition forElement(AnnotatedElement element) {
if (element instanceof Field field) {
Set<Annotation> annotations = getQualifierAnnotations(field);
if (!annotations.isEmpty()) {
return new QualifierDefinition(field, annotations);
}
}
return null;
}
private static Set<Annotation> getQualifierAnnotations(Field field) {
// Assume that any annotations other than @MockBean/@SpyBean are qualifiers
Annotation[] candidates = field.getDeclaredAnnotations();
Set<Annotation> annotations = new HashSet<>(candidates.length);
for (Annotation candidate : candidates) {
if (!isMockOrSpyAnnotation(candidate.annotationType())) {
annotations.add(candidate);
}
}
return annotations;
}
private static boolean isMockOrSpyAnnotation(Class<? extends Annotation> type) {
if (type.equals(MockBean.class) || type.equals(SpyBean.class)) {
return true;
}
MergedAnnotations metaAnnotations = MergedAnnotations.from(type);
return metaAnnotations.isPresent(MockBean.class) || metaAnnotations.isPresent(SpyBean.class);
}
}

View File

@ -1,131 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.mockito.Mockito;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.NativeDetector;
import org.springframework.core.Ordered;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.util.ClassUtils;
/**
* {@link TestExecutionListener} to reset any mock beans that have been marked with a
* {@link MockReset}. Typically used alongside {@link MockitoTestExecutionListener}.
*
* @author Phillip Webb
* @since 1.4.0
* @see MockitoTestExecutionListener
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockitoResetTestExecutionListener}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
public class ResetMocksTestExecutionListener extends AbstractTestExecutionListener {
private static final boolean MOCKITO_IS_PRESENT = ClassUtils.isPresent("org.mockito.MockSettings",
ResetMocksTestExecutionListener.class.getClassLoader());
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 100;
}
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
if (MOCKITO_IS_PRESENT && !NativeDetector.inNativeImage()) {
resetMocks(testContext.getApplicationContext(), MockReset.BEFORE);
}
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
if (MOCKITO_IS_PRESENT && !NativeDetector.inNativeImage()) {
resetMocks(testContext.getApplicationContext(), MockReset.AFTER);
}
}
private void resetMocks(ApplicationContext applicationContext, MockReset reset) {
if (applicationContext instanceof ConfigurableApplicationContext configurableContext) {
resetMocks(configurableContext, reset);
}
}
private void resetMocks(ConfigurableApplicationContext applicationContext, MockReset reset) {
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
String[] names = beanFactory.getBeanDefinitionNames();
Set<String> instantiatedSingletons = new HashSet<>(Arrays.asList(beanFactory.getSingletonNames()));
for (String name : names) {
BeanDefinition definition = beanFactory.getBeanDefinition(name);
if (definition.isSingleton() && instantiatedSingletons.contains(name)) {
Object bean = getBean(beanFactory, name);
if (bean != null && reset.equals(MockReset.get(bean))) {
Mockito.reset(bean);
}
}
}
try {
MockitoBeans mockedBeans = beanFactory.getBean(MockitoBeans.class);
for (Object mockedBean : mockedBeans) {
if (reset.equals(MockReset.get(mockedBean))) {
Mockito.reset(mockedBean);
}
}
}
catch (NoSuchBeanDefinitionException ex) {
// Continue
}
if (applicationContext.getParent() != null) {
resetMocks(applicationContext.getParent(), reset);
}
}
private Object getBean(ConfigurableListableBeanFactory beanFactory, String name) {
try {
if (isStandardBeanOrSingletonFactoryBean(beanFactory, name)) {
return beanFactory.getBean(name);
}
}
catch (Exception ex) {
// Continue
}
return beanFactory.getSingleton(name);
}
private boolean isStandardBeanOrSingletonFactoryBean(ConfigurableListableBeanFactory beanFactory, String name) {
String factoryBeanName = BeanFactory.FACTORY_BEAN_PREFIX + name;
if (beanFactory.containsBean(factoryBeanName)) {
FactoryBean<?> factoryBean = (FactoryBean<?>) beanFactory.getBean(factoryBeanName);
return factoryBean.isSingleton();
}
return true;
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.mockito.plugins.MockResolver;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
import org.springframework.util.Assert;
/**
* A {@link MockResolver} for testing Spring Boot applications with Mockito. It resolves
* mocks by walking the proxy chain until the target or a non-static proxy is found.
*
* @author Andy Wilkinson
* @since 2.4.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's
* {@link MockitoBean} and {@link MockitoSpyBean}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public class SpringBootMockResolver implements MockResolver {
@Override
public Object resolve(Object instance) {
return getUltimateTargetObject(instance);
}
@SuppressWarnings("unchecked")
private static <T> T getUltimateTargetObject(Object candidate) {
Assert.notNull(candidate, "'candidate' must not be null");
try {
if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised advised) {
TargetSource targetSource = advised.getTargetSource();
if (targetSource.isStatic()) {
Object target = targetSource.getTarget();
if (target != null) {
return getUltimateTargetObject(target);
}
}
}
}
catch (Throwable ex) {
throw new IllegalStateException("Failed to unwrap proxied object", ex);
}
return (T) candidate;
}
}

View File

@ -1,150 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Annotation that can be used to apply Mockito spies to a Spring
* {@link ApplicationContext}. Can be used as a class level annotation or on fields in
* either {@code @Configuration} classes, or test classes that are
* {@link RunWith @RunWith} the {@link SpringRunner}.
* <p>
* Spies can be applied by type or by {@link #name() bean name}. All beans in the context
* of a matching type (including subclasses) will be wrapped with the spy. If no existing
* bean is defined a new one will be added. Dependencies that are known to the application
* context but are not beans (such as those
* {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object)
* registered directly}) will not be found and a spied bean will be added to the context
* alongside the existing dependency.
* <p>
* When {@code @SpyBean} is used on a field, as well as being registered in the
* application context, the spy will also be injected into the field. Typical usage might
* be: <pre class="code">
* &#064;RunWith(SpringRunner.class)
* public class ExampleTests {
*
* &#064;SpyBean
* private ExampleService service;
*
* &#064;Autowired
* private UserOfService userOfService;
*
* &#064;Test
* public void testUserOfService() {
* String actual = this.userOfService.makeUse();
* assertEquals("Was: Hello", actual);
* verify(this.service).greet();
* }
*
* &#064;Configuration
* &#064;Import(UserOfService.class) // A &#064;Component injected with ExampleService
* static class Config {
* }
*
*
* }
* </pre> If there is more than one bean of the requested type, qualifier metadata must be
* specified at field level: <pre class="code">
* &#064;RunWith(SpringRunner.class)
* public class ExampleTests {
*
* &#064;SpyBean
* &#064;Qualifier("example")
* private ExampleService service;
*
* ...
* }
* </pre>
* <p>
* This annotation is {@code @Repeatable} and may be specified multiple times when working
* with Java 8 or contained within a {@link SpyBeans @SpyBeans} annotation.
*
* @author Phillip Webb
* @since 1.4.0
* @see MockitoPostProcessor
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(SpyBeans.class)
public @interface SpyBean {
/**
* The name of the bean to spy. If not specified the name will either be generated or,
* if the spy is for an existing bean, the existing name will be used.
* @return the name of the bean
*/
String name() default "";
/**
* The classes to spy. This is an alias of {@link #classes()} which can be used for
* brevity if no other attributes are defined. See {@link #classes()} for details.
* @return the classes to spy
*/
@AliasFor("classes")
Class<?>[] value() default {};
/**
* The classes to spy. Each class specified here will result in a spy being applied.
* Classes can be omitted when the annotation is used on a field.
* <p>
* When {@code @SpyBean} also defines a {@code name} this attribute can only contain a
* single value.
* <p>
* If this is the only specified attribute consider using the {@code value} alias
* instead.
* @return the classes to spy
*/
@AliasFor("value")
Class<?>[] classes() default {};
/**
* The reset mode to apply to the spied bean. The default is {@link MockReset#AFTER}
* meaning that spies are automatically reset after each test method is invoked.
* @return the reset mode
*/
MockReset reset() default MockReset.AFTER;
/**
* Indicates that Mockito methods such as {@link Mockito#verify(Object) verify(mock)}
* should use the {@code target} of AOP advised beans, rather than the proxy itself.
* If set to {@code false} you may need to use the result of
* {@link org.springframework.test.util.AopTestUtils#getUltimateTargetObject(Object)
* AopTestUtils.getUltimateTargetObject(...)} when calling Mockito methods.
* @return {@code true} if the target of AOP advised beans is used or {@code false} if
* the proxy is used directly
*/
boolean proxyTargetAware() default true;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.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;
/**
* Container annotation that aggregates several {@link SpyBean @SpyBean} annotations.
* <p>
* Can be used natively, declaring several nested {@link SpyBean @SpyBean} annotations.
* Can also be used in conjunction with Java 8's support for <em>repeatable
* annotations</em>, where {@link SpyBean @SpyBean} can simply be declared several times
* on the same {@linkplain ElementType#TYPE type}, implicitly generating this container
* annotation.
*
* @author Phillip Webb
* @since 1.4.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of
* {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean}
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface SpyBeans {
/**
* Return the contained {@link SpyBean @SpyBean} annotations.
* @return the spy beans
*/
SpyBean[] value();
}

View File

@ -1,135 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.lang.reflect.Proxy;
import org.mockito.AdditionalAnswers;
import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.mockito.listeners.VerificationStartedEvent;
import org.mockito.listeners.VerificationStartedListener;
import org.springframework.core.ResolvableType;
import org.springframework.core.style.ToStringCreator;
import org.springframework.test.util.AopTestUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import static org.mockito.Mockito.mock;
/**
* A complete definition that can be used to create a Mockito spy.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class SpyDefinition extends Definition {
private static final int MULTIPLIER = 31;
private final ResolvableType typeToSpy;
SpyDefinition(String name, ResolvableType typeToSpy, MockReset reset, boolean proxyTargetAware,
QualifierDefinition qualifier) {
super(name, reset, proxyTargetAware, qualifier);
Assert.notNull(typeToSpy, "'typeToSpy' must not be null");
this.typeToSpy = typeToSpy;
}
ResolvableType getTypeToSpy() {
return this.typeToSpy;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != getClass()) {
return false;
}
SpyDefinition other = (SpyDefinition) obj;
boolean result = super.equals(obj);
result = result && ObjectUtils.nullSafeEquals(this.typeToSpy, other.typeToSpy);
return result;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.typeToSpy);
return result;
}
@Override
public String toString() {
return new ToStringCreator(this).append("name", getName())
.append("typeToSpy", this.typeToSpy)
.append("reset", getReset())
.toString();
}
<T> T createSpy(Object instance) {
return createSpy(getName(), instance);
}
@SuppressWarnings("unchecked")
<T> T createSpy(String name, Object instance) {
Assert.notNull(instance, "'instance' must not be null");
Assert.isInstanceOf(this.typeToSpy.resolve(), instance);
if (Mockito.mockingDetails(instance).isSpy()) {
return (T) instance;
}
MockSettings settings = MockReset.withSettings(getReset());
if (StringUtils.hasLength(name)) {
settings.name(name);
}
if (isProxyTargetAware()) {
settings.verificationStartedListeners(new SpringAopBypassingVerificationStartedListener());
}
Class<?> toSpy;
if (Proxy.isProxyClass(instance.getClass())) {
settings.defaultAnswer(AdditionalAnswers.delegatesTo(instance));
toSpy = this.typeToSpy.toClass();
}
else {
settings.defaultAnswer(Mockito.CALLS_REAL_METHODS);
settings.spiedInstance(instance);
toSpy = instance.getClass();
}
return (T) mock(toSpy, settings);
}
/**
* A {@link VerificationStartedListener} that bypasses any proxy created by Spring AOP
* when the verification of a spy starts.
*/
private static final class SpringAopBypassingVerificationStartedListener implements VerificationStartedListener {
@Override
public void onVerificationStarted(VerificationStartedEvent event) {
event.setMock(AopTestUtils.getUltimateTargetObject(event.getMock()));
}
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright 2012-present 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.
*/
/**
* Mockito integration for Spring Boot tests.
* <p>
* Deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's
* {@link org.springframework.test.context.bean.override.mockito.MockitoBean} and
* {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean}
*/
package org.springframework.boot.test.mock.mockito;

View File

@ -2,13 +2,7 @@
org.springframework.test.context.ContextCustomizerFactory=\
org.springframework.boot.test.context.ImportsContextCustomizerFactory,\
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory
# Test Execution Listeners
org.springframework.test.context.TestExecutionListener=\
org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener,\
org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\

View File

@ -1,30 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
/**
* Concrete implementation of {@link AbstractMockBeanOnGenericTests}.
*
* @author Madhura Bhave
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class AbstractMockBeanOnGenericExtensionTests extends
AbstractMockBeanOnGenericTests<AbstractMockBeanOnGenericTests.ThingImpl, AbstractMockBeanOnGenericTests.SomethingImpl> {
}

View File

@ -1,90 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link MockBean} with abstract class and generics.
*
* @param <T> type of thing
* @param <U> type of something
* @author Madhura Bhave
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@SpringBootTest(classes = AbstractMockBeanOnGenericTests.TestConfiguration.class)
abstract class AbstractMockBeanOnGenericTests<T extends AbstractMockBeanOnGenericTests.Thing<U>, U extends AbstractMockBeanOnGenericTests.Something> {
@Autowired
@SuppressWarnings("unused")
private T thing;
@MockBean
private U something;
@Test
void mockBeanShouldResolveConcreteType() {
assertThat(this.something).isInstanceOf(SomethingImpl.class);
}
abstract static class Thing<T extends AbstractMockBeanOnGenericTests.Something> {
@Autowired
private T something;
T getSomething() {
return this.something;
}
void setSomething(T something) {
this.something = something;
}
}
static class SomethingImpl extends Something {
}
static class ThingImpl extends Thing<SomethingImpl> {
}
static class Something {
}
@Configuration
static class TestConfiguration {
@Bean
ThingImpl thing() {
return new ThingImpl();
}
}
}

View File

@ -1,303 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.example.ExampleExtraInterface;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.RealExampleService;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link DefinitionsParser}.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class DefinitionsParserTests {
private final DefinitionsParser parser = new DefinitionsParser();
@Test
void parseSingleMockBean() {
this.parser.parse(SingleMockBean.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class);
}
@Test
void parseRepeatMockBean() {
this.parser.parse(RepeatMockBean.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class);
assertThat(getMockDefinition(1).getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class);
}
@Test
void parseMockBeanAttributes() {
this.parser.parse(MockBeanAttributes.class);
assertThat(getDefinitions()).hasSize(1);
MockDefinition definition = getMockDefinition(0);
assertThat(definition.getName()).isEqualTo("Name");
assertThat(definition.getTypeToMock().resolve()).isEqualTo(ExampleService.class);
assertThat(definition.getExtraInterfaces()).containsExactly(ExampleExtraInterface.class);
assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS);
assertThat(definition.isSerializable()).isTrue();
assertThat(definition.getReset()).isEqualTo(MockReset.NONE);
assertThat(definition.getQualifier()).isNull();
}
@Test
void parseMockBeanOnClassAndField() {
this.parser.parse(MockBeanOnClassAndField.class);
assertThat(getDefinitions()).hasSize(2);
MockDefinition classDefinition = getMockDefinition(0);
assertThat(classDefinition.getTypeToMock().resolve()).isEqualTo(ExampleService.class);
assertThat(classDefinition.getQualifier()).isNull();
MockDefinition fieldDefinition = getMockDefinition(1);
assertThat(fieldDefinition.getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class);
QualifierDefinition qualifier = QualifierDefinition
.forElement(ReflectionUtils.findField(MockBeanOnClassAndField.class, "caller"));
assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier);
}
@Test
void parseMockBeanInferClassToMock() {
this.parser.parse(MockBeanInferClassToMock.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class);
}
@Test
void parseMockBeanMissingClassToMock() {
assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(MockBeanMissingClassToMock.class))
.withMessageContaining("Unable to deduce type to mock");
}
@Test
void parseMockBeanMultipleClasses() {
this.parser.parse(MockBeanMultipleClasses.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class);
assertThat(getMockDefinition(1).getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class);
}
@Test
void parseMockBeanMultipleClassesWithName() {
assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(MockBeanMultipleClassesWithName.class))
.withMessageContaining("The name attribute can only be used when mocking a single class");
}
@Test
void parseSingleSpyBean() {
this.parser.parse(SingleSpyBean.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
}
@Test
void parseRepeatSpyBean() {
this.parser.parse(RepeatSpyBean.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
assertThat(getSpyDefinition(1).getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class);
}
@Test
void parseSpyBeanAttributes() {
this.parser.parse(SpyBeanAttributes.class);
assertThat(getDefinitions()).hasSize(1);
SpyDefinition definition = getSpyDefinition(0);
assertThat(definition.getName()).isEqualTo("Name");
assertThat(definition.getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
assertThat(definition.getReset()).isEqualTo(MockReset.NONE);
assertThat(definition.getQualifier()).isNull();
}
@Test
void parseSpyBeanOnClassAndField() {
this.parser.parse(SpyBeanOnClassAndField.class);
assertThat(getDefinitions()).hasSize(2);
SpyDefinition classDefinition = getSpyDefinition(0);
assertThat(classDefinition.getQualifier()).isNull();
assertThat(classDefinition.getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
SpyDefinition fieldDefinition = getSpyDefinition(1);
QualifierDefinition qualifier = QualifierDefinition
.forElement(ReflectionUtils.findField(SpyBeanOnClassAndField.class, "caller"));
assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier);
assertThat(fieldDefinition.getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class);
}
@Test
void parseSpyBeanInferClassToMock() {
this.parser.parse(SpyBeanInferClassToMock.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
}
@Test
void parseSpyBeanMissingClassToMock() {
assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(SpyBeanMissingClassToMock.class))
.withMessageContaining("Unable to deduce type to spy");
}
@Test
void parseSpyBeanMultipleClasses() {
this.parser.parse(SpyBeanMultipleClasses.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class);
assertThat(getSpyDefinition(1).getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class);
}
@Test
void parseSpyBeanMultipleClassesWithName() {
assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(SpyBeanMultipleClassesWithName.class))
.withMessageContaining("The name attribute can only be used when spying a single class");
}
private MockDefinition getMockDefinition(int index) {
return (MockDefinition) getDefinitions().get(index);
}
private SpyDefinition getSpyDefinition(int index) {
return (SpyDefinition) getDefinitions().get(index);
}
private List<Definition> getDefinitions() {
return new ArrayList<>(this.parser.getDefinitions());
}
@SuppressWarnings("removal")
@MockBean(ExampleService.class)
static class SingleMockBean {
}
@SuppressWarnings("removal")
@MockBeans({ @MockBean(ExampleService.class), @MockBean(ExampleServiceCaller.class) })
static class RepeatMockBean {
}
@SuppressWarnings("removal")
@MockBean(name = "Name", classes = ExampleService.class, extraInterfaces = ExampleExtraInterface.class,
answer = Answers.RETURNS_SMART_NULLS, serializable = true, reset = MockReset.NONE)
static class MockBeanAttributes {
}
@SuppressWarnings("removal")
@MockBean(ExampleService.class)
static class MockBeanOnClassAndField {
@MockBean(ExampleServiceCaller.class)
@Qualifier("test")
private Object caller;
}
@SuppressWarnings("removal")
@MockBean({ ExampleService.class, ExampleServiceCaller.class })
static class MockBeanMultipleClasses {
}
@SuppressWarnings("removal")
@MockBean(name = "name", classes = { ExampleService.class, ExampleServiceCaller.class })
static class MockBeanMultipleClassesWithName {
}
static class MockBeanInferClassToMock {
@MockBean
private ExampleService exampleService;
}
@SuppressWarnings("removal")
@MockBean
static class MockBeanMissingClassToMock {
}
@SuppressWarnings("removal")
@SpyBean(RealExampleService.class)
static class SingleSpyBean {
}
@SuppressWarnings("removal")
@SpyBeans({ @SpyBean(RealExampleService.class), @SpyBean(ExampleServiceCaller.class) })
static class RepeatSpyBean {
}
@SuppressWarnings("removal")
@SpyBean(name = "Name", classes = RealExampleService.class, reset = MockReset.NONE)
static class SpyBeanAttributes {
}
@SuppressWarnings("removal")
@SpyBean(RealExampleService.class)
static class SpyBeanOnClassAndField {
@SpyBean(ExampleServiceCaller.class)
@Qualifier("test")
private Object caller;
}
@SuppressWarnings("removal")
@SpyBean({ RealExampleService.class, ExampleServiceCaller.class })
static class SpyBeanMultipleClasses {
}
@SuppressWarnings("removal")
@SpyBean(name = "name", classes = { RealExampleService.class, ExampleServiceCaller.class })
static class SpyBeanMultipleClassesWithName {
}
static class SpyBeanInferClassToMock {
@SpyBean
private RealExampleService exampleService;
}
@SuppressWarnings("removal")
@SpyBean
static class SpyBeanMissingClassToMock {
}
}

View File

@ -1,131 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import java.util.Map;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.BootstrapContext;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate;
import org.springframework.test.context.cache.DefaultContextCache;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for application context caching when using {@link MockBean @MockBean}.
*
* @author Andy Wilkinson
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class MockBeanContextCachingTests {
private final DefaultContextCache contextCache = new DefaultContextCache(2);
private final DefaultCacheAwareContextLoaderDelegate delegate = new DefaultCacheAwareContextLoaderDelegate(
this.contextCache);
@AfterEach
@SuppressWarnings("unchecked")
void clearCache() {
Map<MergedContextConfiguration, ApplicationContext> contexts = (Map<MergedContextConfiguration, ApplicationContext>) ReflectionTestUtils
.getField(this.contextCache, "contextMap");
for (ApplicationContext context : contexts.values()) {
if (context instanceof ConfigurableApplicationContext configurableContext) {
configurableContext.close();
}
}
this.contextCache.clear();
}
@Test
void whenThereIsANormalBeanAndAMockBeanThenTwoContextsAreCreated() {
bootstrapContext(TestClass.class);
assertThat(this.contextCache.size()).isOne();
bootstrapContext(MockedBeanTestClass.class);
assertThat(this.contextCache.size()).isEqualTo(2);
}
@Test
void whenThereIsTheSameMockedBeanInEachTestClassThenOneContextIsCreated() {
bootstrapContext(MockedBeanTestClass.class);
assertThat(this.contextCache.size()).isOne();
bootstrapContext(AnotherMockedBeanTestClass.class);
assertThat(this.contextCache.size()).isOne();
}
@SuppressWarnings("rawtypes")
private void bootstrapContext(Class<?> testClass) {
SpringBootTestContextBootstrapper bootstrapper = new SpringBootTestContextBootstrapper();
BootstrapContext bootstrapContext = mock(BootstrapContext.class);
given((Class) bootstrapContext.getTestClass()).willReturn(testClass);
bootstrapper.setBootstrapContext(bootstrapContext);
given(bootstrapContext.getCacheAwareContextLoaderDelegate()).willReturn(this.delegate);
TestContext testContext = bootstrapper.buildTestContext();
testContext.getApplicationContext();
}
@SpringBootTest(classes = TestConfiguration.class)
static class TestClass {
}
@SpringBootTest(classes = TestConfiguration.class)
static class MockedBeanTestClass {
@MockBean
private TestBean testBean;
}
@SpringBootTest(classes = TestConfiguration.class)
static class AnotherMockedBeanTestClass {
@MockBean
private TestBean testBean;
}
@Configuration
static class TestConfiguration {
@Bean
TestBean testBean() {
return new TestBean();
}
}
static class TestBean {
}
}

View File

@ -1,98 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test {@link MockBean @MockBean} for a factory bean.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
class MockBeanForBeanFactoryIntegrationTests {
// gh-7439
@MockBean
private TestFactoryBean testFactoryBean;
@Autowired
private ApplicationContext applicationContext;
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
void testName() {
TestBean testBean = mock(TestBean.class);
given(testBean.hello()).willReturn("amock");
given(this.testFactoryBean.getObjectType()).willReturn((Class) TestBean.class);
given(this.testFactoryBean.getObject()).willReturn(testBean);
TestBean bean = this.applicationContext.getBean(TestBean.class);
assertThat(bean.hello()).isEqualTo("amock");
}
@Configuration(proxyBeanMethods = false)
static class Config {
@Bean
TestFactoryBean testFactoryBean() {
return new TestFactoryBean();
}
}
static class TestFactoryBean implements FactoryBean<TestBean> {
@Override
public TestBean getObject() {
return () -> "normal";
}
@Override
public Class<?> getObjectType() {
return TestBean.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
interface TestBean {
String hello();
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a configuration class can be used to replace
* existing beans.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
class MockBeanOnConfigurationClassForExistingBeanIntegrationTests {
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.caller.getService().greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@SuppressWarnings("removal")
@Configuration(proxyBeanMethods = false)
@MockBean(ExampleService.class)
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
static class Config {
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a configuration class can be used to inject new mock
* instances.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@ExtendWith(SpringExtension.class)
@Deprecated(since = "3.4.0", forRemoval = true)
class MockBeanOnConfigurationClassForNewBeanIntegrationTests {
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.caller.getService().greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@SuppressWarnings("removal")
@Configuration(proxyBeanMethods = false)
@MockBean(ExampleService.class)
@Import(ExampleServiceCaller.class)
static class Config {
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a field on a {@code @Configuration} class can be
* used to replace existing beans.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@ExtendWith(SpringExtension.class)
@Deprecated(since = "3.4.0", forRemoval = true)
class MockBeanOnConfigurationFieldForExistingBeanIntegrationTests {
@Autowired
private Config config;
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.config.exampleService.greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@Configuration(proxyBeanMethods = false)
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
static class Config {
@MockBean
private ExampleService exampleService;
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a field on a {@code @Configuration} class can be
* used to inject new mock instances.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@ExtendWith(SpringExtension.class)
@Deprecated(since = "3.4.0", forRemoval = true)
class MockBeanOnConfigurationFieldForNewBeanIntegrationTests {
@Autowired
private Config config;
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.config.exampleService.greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@Configuration(proxyBeanMethods = false)
@Import(ExampleServiceCaller.class)
static class Config {
@MockBean
private ExampleService exampleService;
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test {@link MockBean @MockBean} can be used with a
* {@link ContextHierarchy @ContextHierarchy}.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
@ContextHierarchy({ @ContextConfiguration(classes = MockBeanOnContextHierarchyIntegrationTests.ParentConfig.class),
@ContextConfiguration(classes = MockBeanOnContextHierarchyIntegrationTests.ChildConfig.class) })
class MockBeanOnContextHierarchyIntegrationTests {
@Autowired
private ChildConfig childConfig;
@Test
void testMocking() {
ApplicationContext context = this.childConfig.getContext();
ApplicationContext parentContext = context.getParent();
assertThat(parentContext
.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class)).hasSize(1);
assertThat(parentContext
.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class))
.isEmpty();
assertThat(context.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class))
.isEmpty();
assertThat(context
.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class))
.hasSize(1);
assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleService.class))
.isNotNull();
assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class))
.isNotNull();
}
@Configuration(proxyBeanMethods = false)
@MockBean(org.springframework.boot.test.mock.mockito.example.ExampleService.class)
static class ParentConfig {
}
@Configuration(proxyBeanMethods = false)
@MockBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)
static class ChildConfig implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
ApplicationContext getContext() {
return this.context;
}
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} when used in combination with scoped proxy targets.
*
* @author Phillip Webb
* @see <a href="https://github.com/spring-projects/spring-boot/issues/5724">gh-5724</a>
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
class MockBeanOnScopedProxyTests {
@MockBean
private ExampleService exampleService;
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.caller.getService().greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@Configuration(proxyBeanMethods = false)
@Import({ ExampleServiceCaller.class })
static class Config {
@Bean
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
ExampleService exampleService() {
return new FailingExampleService();
}
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a test class can be used to replace existing beans.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
@MockBean(ExampleService.class)
class MockBeanOnTestClassForExistingBeanIntegrationTests {
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.caller.getService().greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@Configuration(proxyBeanMethods = false)
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
static class Config {
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a test class can be used to inject new mock
* instances.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
@MockBean(ExampleService.class)
class MockBeanOnTestClassForNewBeanIntegrationTests {
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.caller.getService().greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
@Configuration(proxyBeanMethods = false)
@Import(ExampleServiceCaller.class)
static class Config {
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a test class field can be used to replace existing
* beans when the context is cached. This test is identical to
* {@link MockBeanOnTestFieldForExistingBeanIntegrationTests} so one of them should
* trigger application context caching.
*
* @author Phillip Webb
* @see MockBeanOnTestFieldForExistingBeanIntegrationTests
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = MockBeanOnTestFieldForExistingBeanConfig.class)
class MockBeanOnTestFieldForExistingBeanCacheIntegrationTests {
@MockBean
private ExampleService exampleService;
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.exampleService.greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Config for {@link MockBeanOnTestFieldForExistingBeanIntegrationTests} and
* {@link MockBeanOnTestFieldForExistingBeanCacheIntegrationTests}. Extracted to a shared
* config to trigger caching.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@Configuration(proxyBeanMethods = false)
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
public class MockBeanOnTestFieldForExistingBeanConfig {
}

View File

@ -1,57 +0,0 @@
/*
* Copyright 2012-present 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.boot.test.mock.mockito;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.example.ExampleService;
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test {@link MockBean @MockBean} on a test class field can be used to replace existing
* beans.
*
* @author Phillip Webb
* @see MockBeanOnTestFieldForExistingBeanCacheIntegrationTests
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = MockBeanOnTestFieldForExistingBeanConfig.class)
class MockBeanOnTestFieldForExistingBeanIntegrationTests {
@MockBean
private ExampleService exampleService;
@Autowired
private ExampleServiceCaller caller;
@Test
void testMocking() {
given(this.exampleService.greeting()).willReturn("Boot");
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
}
}

Some files were not shown because too many files have changed in this diff Show More