Junit, ServletContextAware y MockServletContext

Se me generó el siguiente problema al hacer un test unitario sobre una clase que implementa la interfaz de Spring Framework ServletContextAware.

1
2
3
4
5
public interface ServletContextAware {

void setServletContext(ServletContext servletContext);

}

Mediante esta interfaz puedes inyectar el servletContext a la configuración de tu Bean, siempre y cuando tengas un contexto web funcionando.

He aquí el segundo problema, ¿ Cómo puedo tener el un contexto web dentro de un Junit ?. Puede que exista una mejor forma de hacerlo pero lo logré de la siguiente manera.

1
2
3
4
5
6
7
8
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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-3.0.xsd" xmlns:p="http://www.springframework.org/schema/p">

<bean class="org.springframework.mock.web.MockServletContext" />

</beans>

Con esto y usando la anotación Autowired funciona de pelos la inyección del ServletContext.

1
2
3
4
5
6
7
public class ReadFileFromWebinf {

@Autowired
private ServletContext _servletContext;

/*Se omite el resto de los métodos*/
}

Pero!!! cuando quise utilizar la interfaz ServletContextAware no funcionó y me quede con una propiedad en null.

1
2
3
4
5
6
7
8
9
10
public class ReadFileFromWebinf implement ServletContextAware {

private ServletContext _servletContext;

public void setServletContext(ServletContext servletContext){
_servletContext=servletContext;
};

/*Se omite el resto de los métodos*/
}

Buscando por todos lados encontré que a mi test unitario le faltaba un par de configuraciones para la lectura del contexto Spring.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test/test-context.xml" }
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
public class ReadFileFromWebinfTest {

@Autowired
private ReadFileFromWebinf _readFileFromWebinf;


public void testReadFile(){
String fileContent = _readFileFromWebinf.load("archivo.xml");
System.out.println(fileContent);
}
}

Las dos primeras anotaciones son para decirle a Spring que se va a utilizar Junit para ejecutar la clase y cual o cuales son los contextos a cargar.

Luego viene la anotación que me arregló el día, TestExecutionListeners y el listener asociado para la completar las inyecciones de dependencia de todos los beans. (Antes con Autowired solo hacía algunos).

Espero les sirva, cualquier duda bienvenida sea.