Remove duplicate dispatcher servlet auto-config tests

Closes gh-44207
This commit is contained in:
Andy Wilkinson 2025-02-11 12:10:33 +00:00
parent 5c8d9d910a
commit 3e5929a446
2 changed files with 23 additions and 147 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 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.
@ -65,10 +65,18 @@ class DispatcherServletAutoConfigurationTests {
});
}
// If a DispatcherServlet instance is registered with a name different
// from the default one, we're registering one anyway
@Test
void registrationOverrideWithDispatcherServletWrongName() {
void registrationOverrideWithDefaultDispatcherServletNameResultsInSingleDispatcherServlet() {
this.contextRunner.withUserConfiguration(CustomDispatcherServletSameName.class).run((context) -> {
ServletRegistrationBean<?> registration = context.getBean(ServletRegistrationBean.class);
assertThat(registration.getUrlMappings()).containsExactly("/");
assertThat(registration.getServletName()).isEqualTo("dispatcherServlet");
assertThat(context).getBeanNames(DispatcherServlet.class).hasSize(1);
});
}
@Test
void registrationOverrideWithNonDefaultDispatcherServletNameResultsInTwoDispatcherServlets() {
this.contextRunner
.withUserConfiguration(CustomDispatcherServletDifferentName.class, CustomDispatcherServletPath.class)
.run((context) -> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 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.
@ -19,10 +19,7 @@ package org.springframework.boot.autoconfigure.web.servlet;
import io.undertow.Undertow.Builder;
import io.undertow.servlet.api.DeploymentInfo;
import jakarta.servlet.Filter;
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
@ -34,10 +31,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
@ -49,19 +43,15 @@ import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCust
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.ForwardedHeaderFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.FrameworkServlet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@ -77,69 +67,31 @@ import static org.mockito.Mockito.mock;
* @author Raheela Aslam
* @author Madhura Bhave
*/
@DirtiesUrlFactories
class ServletWebServerFactoryAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(
AnnotationConfigServletWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class,
DispatcherServletAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(WebServerConfiguration.class);
@Test
void createFromConfigClass() {
this.contextRunner.run(verifyContext());
}
@Test
void contextAlreadyHasDispatcherServletWithDefaultName() {
this.contextRunner.withUserConfiguration(DispatcherServletConfiguration.class).run(verifyContext());
}
@Test
void contextAlreadyHasDispatcherServlet() {
this.contextRunner.withUserConfiguration(SpringServletConfiguration.class).run((context) -> {
verifyContext(context);
assertThat(context.getBeanNamesForType(DispatcherServlet.class)).hasSize(2);
});
}
@Test
void contextAlreadyHasNonDispatcherServlet() {
this.contextRunner.withUserConfiguration(NonSpringServletConfiguration.class).run((context) -> {
verifyContext(context); // the non default servlet is still registered
assertThat(context).doesNotHaveBean(DispatcherServlet.class);
});
}
@Test
void contextAlreadyHasNonServlet() {
this.contextRunner.withUserConfiguration(NonServletConfiguration.class).run((context) -> {
assertThat(context).doesNotHaveBean(DispatcherServlet.class);
assertThat(context).doesNotHaveBean(Servlet.class);
});
}
@Test
void contextAlreadyHasDispatcherServletAndRegistration() {
this.contextRunner.withUserConfiguration(DispatcherServletWithRegistrationConfiguration.class)
.run((context) -> {
verifyContext(context);
assertThat(context).hasSingleBean(DispatcherServlet.class);
});
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ServletWebServerFactoryCustomizer.class));
}
@Test
void webServerHasNoServletContext() {
this.contextRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class).run(verifyContext());
this.contextRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class)
.run((context) -> assertThat(context).hasNotFailed());
}
@Test
void customizeWebServerFactoryThroughCallback() {
this.contextRunner.withUserConfiguration(CallbackEmbeddedServerFactoryCustomizer.class).run((context) -> {
verifyContext(context);
assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000);
});
void webServerFactoryCustomizerBeansAreCalledToCustomizeWebServerFactory() {
this.contextRunner
.withBean(WebServerFactoryCustomizer.class,
() -> (WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>) (factory) -> factory
.setPort(9000))
.run((context) -> assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000));
}
@Test
@ -424,17 +376,6 @@ class ServletWebServerFactoryAutoConfigurationTests {
});
}
private ContextConsumer<AssertableWebApplicationContext> verifyContext() {
return this::verifyContext;
}
private void verifyContext(ApplicationContext context) {
MockServletWebServerFactory factory = context.getBean(MockServletWebServerFactory.class);
Servlet servlet = context.getBean(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME,
Servlet.class);
then(factory.getServletContext()).should().addServlet("dispatcherServlet", servlet);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnExpression("true")
static class WebServerConfiguration {
@ -446,68 +387,6 @@ class ServletWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DispatcherServletConfiguration {
@Bean
DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
}
@Configuration(proxyBeanMethods = false)
static class SpringServletConfiguration {
@Bean
DispatcherServlet springServlet() {
return new DispatcherServlet();
}
}
@Configuration(proxyBeanMethods = false)
static class NonSpringServletConfiguration {
@Bean
FrameworkServlet dispatcherServlet() {
return new FrameworkServlet() {
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) {
}
};
}
}
@Configuration(proxyBeanMethods = false)
static class NonServletConfiguration {
@Bean
String dispatcherServlet() {
return "foo";
}
}
@Configuration(proxyBeanMethods = false)
static class DispatcherServletWithRegistrationConfiguration {
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
ServletRegistrationBean<DispatcherServlet> dispatcherRegistration(DispatcherServlet dispatcherServlet) {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(dispatcherServlet,
"/app/*");
registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
return registration;
}
}
@Component
static class EnsureWebServerHasNoServletContext implements BeanPostProcessor {
@ -527,17 +406,6 @@ class ServletWebServerFactoryAutoConfigurationTests {
}
@Component
static class CallbackEmbeddedServerFactoryCustomizer
implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory serverFactory) {
serverFactory.setPort(9000);
}
}
@Configuration(proxyBeanMethods = false)
static class TomcatConnectorCustomizerConfiguration {