tutorial starter mvc initializr example java spring spring-mvc spring-boot gradle

java - starter - spring mvc example



¿Cómo cargar propiedades de recursos en un contexto JUnit Spring en un proyecto multi Gradle? (1)

¿Hay algún motivo particular por el que esté utilizando AnnotationConfigContextLoader lugar de (por defecto) SpringBootContextLoader ? El problema al que se enfrenta no es causado por la falta del archivo en la classpath (puede copiar application-test.yaml en cualquier src/main/resources o src/test/resources con el mismo resultado) pero el hecho de que AnnotationConfigContextLoader no usa ConfigFileApplicationListener Es responsable de configurar el contexto cargando propiedades desde ubicaciones de archivos conocidas (como application-{profile}.yaml en su caso).

Puede comparar fácilmente qué propiedades se cargan al usar cada cargador. En primer lugar, puede verificar qué hace AnnotationConfigContextLoader : simplemente coloque un punto de interrupción en la línea 128 del archivo AbstractGenericContextLoader.java y ejecute el depurador en su IDE favorito:

A continuación, puede investigar el context variable -> environment -> propertySources -> propertySourceList . Encontrarás 5 fuentes de propiedad:

Ninguno de ellos carga propiedades desde archivos de configuración como application.yml o application.properties .

Ahora hagamos lo mismo, pero con la clase SpringBootContextLoader . Primero eliminar

loader = AnnotationConfigContextLoader.class

en MyEntityTest y poner un punto de interrupción en la línea 303 en el archivo SpringApplication.java:

Aquí estamos justo antes de que el contexto de la aplicación se actualice. Ahora investiguemos el context variable -> environment -> propertySources -> propertySourceList :

La primera diferencia que podemos ver es que ahora tenemos 7 fuentes de propiedad en lugar de 5 como en el ejemplo anterior. Y lo más importante: ConfigFileApplicationListener.ConfigurationPropertySources está aquí. Esta clase hace que el contexto de la application-{profile}.yaml en cuenta la existencia del archivo de propiedades de la application-{profile}.yaml .

Como puede ver, solo se trata de usar el cargador de contexto correcto. Reemplazar

@ContextConfiguration(classes = { ChildCConfig.class }, loader = AnnotationConfigContextLoader.class)

con

@ContextConfiguration(classes = { ChildCConfig.class }, loader = SpringBootContextLoader.class)

o

@ContextConfiguration(classes = { ChildCConfig.class })

ya que este cargador es el predeterminado al usar la anotación @SpringBootTest y hará que su prueba pase como un amuleto. Espero que ayude.

Tengo el siguiente árbol de proyectos:

├── app │   ├── build.gradle │   └── src │   ├── main │   │   ├── java │   │   │   └── child │   │   │   └── app │   │   │   └── Application.java │   │   └── resources │   │   └── application-default.yaml │   └── test │   └── java │   └── child │   └── app │   └── ApplicationTest.java ├── build.gradle ├── childA │   ├── build.gradle │   └── src │   └── main │   └── java │   └── child │   └── a │   ├── BaseGreeterImpl.java │   ├── ChildAConfig.java │   ├── Greeter.java │   └── MySpringProperties.java ├── childB │   ├── build.gradle │   └── src │   └── main │   └── resources │   ├── application-test.yaml │   └── childB.properties ├── childC │   ├── build.gradle │   └── src │   ├── main │   │   ├── java │   │   │   └── child │   │   │   └── c │   │   │   ├── ChildCConfig.java │   │   │   └── PropertyGreeterImpl.java │   │   └── resources │   │   └── childc.properties │   └── test │   └── java │   └── child │   └── c │   ├── TestYamlImport.java │   └── TestGreeter.java └── settings.gradle

Tengo la siguiente clase de prueba:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { ChildCConfig.class }, loader = AnnotationConfigContextLoader.class) @ActiveProfiles("test") @SpringBootTest public class TestYamlImport { @Autowired private MySpringProperties properties; @Test public void readChildAYaml() { assertThat(properties.getName()).isEqualTo("it-is-another-thing"); } }

Esperado

Espero que properties.getName() lea el valor del recurso childB en childB / src / main / resources / application-test.yaml .

Resultado

Obtengo null

Reproducción

GitHub: https://github.com/kopax/adk/tree/adk-spring

Un trazador de líneas:

git clone [email protected]:kopax/adk.git && cd adk && git checkout adk-spring && ./gradlew build --info

Pregunta

Hay una prueba llamada childC / src / test / java / childC / TestGreeter.java en el proyecto de reproducción que prueba con childB.properties importar que no es un problema de classpath .

Asi que aqui están mis preguntas :

  • ¿Está la primavera limitando la resolución de la ruta de @ConfigurationProperties alguna manera cuando se usa @ConfigurationProperties ?

  • No he encontrado una manera de leer mi application-test.yml dentro de una configuración @Bean inicializada en childA desde el alcance de prueba de childB , ¿cómo es posible?