lunes, 21 de enero de 2008

JUnit con Spring

En ocasiones es necesario poder realizar pruebas unitarias sobre algunos componentes que ya hemos configurado previamente en Spring, esto se convierte en algo un poco complicado pues es un hecho que ahora no podemos acceder de manera simple o directa a nuestros beans, dado que la instanciación de los mismos esta en manos de Spring.

Para solucionar este problema podemos hacer uso de los métodos setUp de TestCase y de unas simples instrucciones para poder realizar las pruebas; la idea simplemente es cargar un BeanFactory que tenga la misma configuración que tendría nuestro entorno Web y poder desde este factory obtener los beans.

Una aproximación a este problema podría incluir cargar un Mock del servlet container para cargar todo. Esto presenta sus ventajas pero en lo personal me agradan las soluciones simples.

Para empezar, podemos crear un simple Resource que nos indique donde esta nuestro archivo de beans:


Resource res = new ClassPathResource("applicationContext.xml");


Esto debería cargar el archivo applicationContext.xml desde el classpath. Si el archivo esta dentro de WEB-INF/clases pues la carga se realiza sin problemas, pero si esto no funciona aún queda la solución de usar un FileSystemResource, esto no afectara de manera significativa las pruebas.

A partir de nuestra instancia de recurso podemos crear un BeanFactory que se configure por medio de XML para poder acceder a nuestros beans:


XmlBeanFactory factory = new XmlBeanFactory(res)


Y listo, tenemos una instancia que podemos usar para obtener nuestros beans. En contra de esta solución puedo decir que no puedes conservar todos los scopes de Spring, pero en un UnitTest no deberías tener tantas dependencías.

Ahora, si podemos esto en una clase de TestCase...


public class BasicSpringTestCase extends TestCase {
protected XmlBeanFactory factory = null;

protected void setUp() {
Resource res = new ClassPathResource("applicationContext.xml");
factory = new XmlBeanFactory(res);
}
}

//Aquí ya no necesitamos hacer nada... solamente consumir nuestros beans
public class TestSpring extends BasicSpringTestCase {
public void testSomething() {
Object bean = factory.getBean("id_bean");
}
}