Lo que hacemos en nuestro proyecto es simplemente escribir una prueba JUnit que carga la configuración de Spring. Esto hace unas pocas de las cosas que ha descrito como:
- Validar el código XML
- Asegura granos se pueden cargar con clases en la ruta de clase (por lo menos los granos que no son perezosos-cargado)
No comprueba que no haya granos huérfanos. No existe una manera confiable de hacer esto de todos modos, considerando desde cualquier parte de su código, puede buscar beans directamente dado su ID. Solo porque un frijol no esté referenciado por ningún otro frijol no significa que no se use. De hecho, todas las configuraciones de Spring tendrán al menos un bean al que no hacen referencia otros beans porque siempre debe haber una raíz para la jerarquía.
Si tiene granos que se basan en reales servicios como bases de datos o algo y no desea conectarse a estos servicios en una prueba unitaria, simplemente necesita para abstraer la configuración para permitir valores de prueba. Esto se puede lograr fácilmente con algo como el PropertyPlaceholderConfigurer que le permite tener diferentes propiedades especificadas en archivos de configuración separados para cada entorno y luego referenciadas por un archivo de definición de beans.
EDITAR (incluir código de ejemplo):
La forma de hacer esto es tener al menos 3 archivos diferentes primavera ...
- src/main/resources/applicationContext.xml
- src/main/resources/beanDefinitions.xml
- src/test/resources/testContext.xml
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="classpath:beanDefinitions.xml"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:path/environment.properties" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}" />
...
</bean>
... <!-- more beans which shouldn't be loaded in a test go here -->
</beans>
beanDefinitions.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myBean" class="com.example.MyClass">
...
</bean>
<bean id="myRepo" class="com.example.MyRepository">
<property name="dataSource" ref="dataSource"/>
...
</bean>
... <!-- more beans which should be loaded in a test -->
</beans>
testContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="classpath:beanDefinitions.xml"/>
<bean id="dataSource" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.jdbc.datasource.DriverManagerDataSource"/>
</bean>
</beans>
Hay muchas cosas que suceden aquí, vamos a explicar ...
- El archivo applicationContext.xml es la archivo principal de primavera para toda su aplicación. Contiene un bean PropertyPlaceHolder para permitir que ciertos valores de propiedades sean configurables entre diferentes entornos en los que implementamos (prueba frente a prod). Importa todos los beans principales que la aplicación necesita para ejecutarse. Cualquier frijol que no se deba usar en una prueba, como beans de DB u otras clases que se comuniquen con servicios/recursos externos, debe definirse en este archivo.
- El archivo beanDefinitions.xml tiene todos sus beans normales que no dependen de elementos externos. Estos beans pueden y harán referencia a beans definidos en el archivo appContext.xml.
- El archivo testContext.xml es la versión de prueba de appContext. Necesita versiones de todos los beans definidos en el archivo appContext.xml, pero usamos una biblioteca de burla para crear una instancia de estos beans. De esta forma, las clases reales no se utilizan y no existe el riesgo de acceder a recursos externos. Este archivo tampoco necesita la propiedad placeholder bean.
Ahora que tenemos un contexto de prueba que no tenemos miedo a cargar de una prueba, aquí está el código para hacerlo ...
SpringContextTest.java paquete com.example;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class SpringContextTest {
@Test
public void springContextCanLoad() {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("testContext.xml"));
for (String beanName : factory.getBeanDefinitionNames()) {
Object bean = factory.getBean(beanName);
// assert anything you want
}
}
}
Esta puede no ser la forma óptima de hacerlo; la clase ApplicationContext es la forma recomendada de cargar contextos de primavera. Lo anterior podría ser capaz de ser reemplazado por:
@Test
public void springContextCanLoad() {
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:testContext.xml");
}
creo que una línea va a lograr todo lo que necesita para verificar su contexto muelle está conectado correctamente. A partir de ahí, puede cargar frijoles y afirmar como antes.
Espero que esto ayude!
En medio de un proyecto marcha de la muerte y tenía la esperanza de encontrar una solución automagic-pensamiento cero, pero haces buenos puntos. Supongo que en realidad tengo que pensar un poco. Queja. Gracias. – Ickster
Gweebz, ¿te molesta compartir el código fuente para esto? Me encantaría tener esta prueba JUnit en mi proyecto. –
@Cory - Trataré de encontrar este código para ti, era un proyecto en el que trabajé hace un tiempo, así que tendré que buscar en SVN. –