¿Cómo se excluyen las clases * AutoConfiguration en Spring Boot JUnit tests?

Lo intenté:

@RunWith(SpringJUnit4ClassRunner.class) @EnableAutoConfiguration(exclude=CrshAutoConfiguration.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class LikeControllerTest { 

Sin embargo, el CRaSSHD aún se inicia. Aunque actualmente no daña la prueba, me gustaría deshabilitar los módulos innecesarios durante las pruebas unitarias para acelerar y también evitar posibles conflictos.

Tuve un caso de uso similar en el que quería probar un repository configurado de Spring Boot de forma aislada (en mi caso, sin la configuración automática de Spring Security que no pasaba la prueba). @SpringApplicationConfiguration utiliza SpringApplicationContextLoader y tiene una statement JavaDoc

Se puede usar para probar funciones no web (como una capa de repository) o iniciar un contenedor de servlet incorporado totalmente configurado.

Sin embargo, como usted, no pude determinar cómo se debe configurar la prueba para que solo pruebe la capa de repository utilizando el punto de entrada de la configuración principal, es decir, utilizando su enfoque de @SpringApplicationConfiguration(classes = Application.class) .

Mi solución fue crear un contexto de aplicación completamente nuevo exclusivo para las pruebas. Entonces en src / test / java tengo dos archivos en un subpaquete llamado repo

  1. RepoIntegrationTest.java
  2. TestRepoConfig.java

donde RepoIntegrationTest.java tiene

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestRepoConfig.class) public class RepoIntegrationTest { 

y TestRepoConfig.java tiene

 @SpringBootApplication(exclude = SecurityAutoConfiguration.class) public class TestRepoConfig { 

Me sacó de problemas, pero sería muy útil si alguien del equipo de Spring Boot pudiera proporcionar una solución alternativa recomendada

Otra forma simple de excluir las clases de configuración automática,

Agregue a continuación una configuración similar a su archivo application.yml ,

 --- spring: profiles: test autoconfigure.exclude: org.springframework.boot.autoconfigure.session.SessionAutoConfiguration 

Tuve un problema similar pero llegué a una solución diferente que puede ayudar a otros. Utilicé Spring Profiles para separar las pruebas y las clases de configuración de la aplicación.

  1. Cree una clase TestConfig con un perfil específico y excluya cualquier configuración de aplicación del análisis de componentes que desee aquí.

  2. En su clase de prueba, configure el perfil para que coincida con TestConfig e inclúyalo usando la anotación @ContextConfiguration.

Por ejemplo:

configuración:

 @Profile("test") @Configuration @EnableWebMvc @ComponentScan( basePackages="your.base.package", excludeFilters = { @Filter(type = ASSIGNABLE_TYPE, value = { ExcludedAppConfig1.class, ExcludedAppConfig2.class }) }) public class TestConfig { ...} 

prueba:

 @ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = TestConfig.class) @WebAppConfiguration public class SomeTest{ ... } 

Con la nueva anotación @SpringBootTest , tomé esta respuesta y la modifiqué para usar perfiles con una clase de configuración @SpringBootApplication . La anotación @Profile es necesaria para que esta clase solo se @Profile durante las pruebas de integración específicas que lo necesiten, ya que otras configuraciones de prueba realizan un escaneo de componentes diferente.

Aquí está la clase de configuración:

 @Profile("specific-profile") @SpringBootApplication(scanBasePackages={"com.myco.package1", "com.myco.package2"}) public class SpecificTestConfig { } 

Entonces, la clase de prueba hace referencia a esta clase de configuración:

 @RunWith(SpringRunner.class) @SpringBootTest(classes = { SpecificTestConfig.class }) @ActiveProfiles({"specific-profile"}) public class MyTest { } 

Creo que usar la anotación @EnableAutoConfiguration en una clase de prueba no funcionará si está utilizando @SpringApplicationConfiguration para cargar su clase de Application . Lo que pasa es que ya tiene una anotación @EnableAutoConfiguration en la clase de la Application que no excluye la CrshAutoConfiguration . Spring usa esa anotación en lugar de la que está en su clase de prueba para hacer la configuración automática de sus beans.

Creo que su mejor opción es utilizar un contexto de aplicación diferente para sus pruebas y excluir la CrshAutoConfiguration en esa clase.

Hice algunas pruebas y parece que @EnableAutoConfiguration en la clase de prueba es completamente ignorada si está utilizando la anotación @SpringApplicationConfiguration y SpringJUnit4ClassRunner .

metido en el mismo tipo de problema, no fue capaz de excluir la clase principal de arranque durante la prueba. Lo resolvió usando el siguiente enfoque.

En lugar de usar @SpringBootApplication, use las tres anotaciones que contiene y asigne el nombre a @Configuration

 @Configuration("myApp") @EnableAutoConfiguration @ComponentScan public class MyApp { .. } 

En su clase de prueba, defina la configuración con exactamente el mismo nombre:

 @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration // ugly hack how to exclude main configuration @Configuration("myApp") @SpringApplicationConfiguration(classes = MyTest.class) public class MyTest { ... } 

Esto debería ayudar. Sería bueno tener una manera mejor en el lugar de cómo deshabilitar el escaneo automático para las anotaciones de configuración …

 @SpringBootTest(classes = {Application.class} , webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT , properties="spring.autoconfigure.exclude=com.xx.xx.AutoConfiguration" ) 

ref: https://github.com/spring-projects/spring-boot/issues/8579

Luché con esto también y encontré un patrón simple para aislar el contexto de prueba después de una lectura superficial de los documentos de @ComponentScan .

/ **
* Alternativa de tipo seguro para {@link #basePackages} para especificar los paquetes
* para buscar componentes anotados. El paquete de cada clase especificada será escaneado.
* Considere la posibilidad de crear una clase o interfaz de marcador especial sin oposición en cada paquete
* que no tiene otra finalidad que no sea hacer referencia a este atributo.
* /
Class[] basePackageClasses() default {};

  1. Crea un paquete para tus pruebas de spring ("com.example.test") .
  2. Cree una interfaz de marcador en el paquete como un calificador de contexto.
  3. Proporcione la referencia de interfaz de marcador como parámetro para basePackageClasses.

Ejemplo


IsolatedTest.java

 package com.example.test; @RunWith(SpringJUnit4ClassRunner.class) @ComponentScan(basePackageClasses = {TestDomain.class}) @SpringApplicationConfiguration(classes = IsolatedTest.Config.class) public class IsolatedTest { String expected = "Read the documentation on @ComponentScan"; String actual = "Too lazy when I can just search on Stack Overflow."; @Test public void testSomething() throws Exception { assertEquals(expected, actual); } @ComponentScan(basePackageClasses = {TestDomain.class}) public static class Config { public static void main(String[] args) { SpringApplication.run(Config.class, args); } } } ... 

TestDomain.java

 package com.example.test; public interface TestDomain { //noop marker } 

Si tiene este problema con Spring Boot 1.4.xy superior, es posible que pueda usar @OverrideAutoConfiguration(enabled=true) para resolver el problema.

Similar a lo que se preguntó / respondió aquí https://stackoverflow.com/a/39253304/1410035

Si el problema es que su SpringBootApplication / Configuration que está incorporando es un componente que escanea el paquete en el que se encuentran sus configuraciones de prueba, puede eliminar la anotación @Configuration de las configuraciones de prueba y todavía puede usarlas en las anotaciones @SpringBootTest. Por ejemplo, si tiene una aplicación de clase que es su configuración principal y una clase TestConfiguration que es una configuración para ciertas pruebas, pero no todas, puede configurar sus clases de la siguiente manera:

 @Import(Application.class) //or the specific configurations you want //(Optional) Other Annotations that will not trigger an autowire public class TestConfiguration { //your custom test configuration } 

Y luego puede configurar sus pruebas de una de estas dos formas:

  1. Con la configuración regular:

     @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation //Other annotations here public class TestThatUsesNormalApplication { //my test code } 
  2. Con la configuración de prueba de prueba personalizada:

     @SpringBootTest(classes = {TestConfiguration.class}) //this still works! //Other annotations here public class TestThatUsesCustomTestConfiguration { //my test code }