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 enchildA
desde el alcance de prueba dechildB
, ¿cómo es posible?