2012-07-03 47 views
22

Desde Spring 3.1, podemos usar JavaConfig más fácilmente gracias a las anotaciones @Enable*.¿Por qué falla la prueba unitaria con Spring 3.1 WebMvcConfig?

Así que hice un WebConfig para establecer la configuración de WebMvc, y traté de probarlo. Pero si amplío WebMvcConfigurerAdapter o WebMvcConfigurationSupport con WebConfig, la prueba de la unidad falla debido a la falta de ServletContext. El código y los mensajes se ven a continuación.

WebConfig.java

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurationSupport {} 

Test.java

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes=WebConfig.class) 
public class TestFail { 
    @Test 
    public void test() {} 
} 

mensaje

java.lang.IllegalStateException: Failed to load ApplicationContext 
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
... 
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling 
    at org.springframework.util.Assert.notNull(Assert.java:112) 
    at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54) 
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:253) 
    at com.zum.news.comments.web.WebConfig$$EnhancerByCGLIB$$8bbfcca1.CGLIB$defaultServletHandlerMapping$10(<generated>) 
    at com.zum.news.comments.web.WebConfig$$EnhancerByCGLIB$$8bbfcca1$$FastClassByCGLIB$$19b86ad0.invoke(<generated>) 
    at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:215) 
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280) 
    at com.zum.news.comments.web.WebConfig$$EnhancerByCGLIB$$8bbfcca1.defaultServletHandlerMapping(<generated>) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149) 
    ... 41 more 

Cómo probar la unidad de WebConfig correctamente?

Editar

Como dijo García, este error se corrige en la primavera 3.2.0.RC1.

Simplemente agregue la anotación @WebAppConfiguration en la clase de prueba.

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes=WebConfig.class) 
public class TestFail { 
    @Test 
    public void test() {} 
} 
+1

No entiendo cómo esta pregunta tiene tan pocos votos. Supongo que hay personas tratando de hacer pruebas de integración con las sutilezas de Spring 3.1 ... –

+1

La pregunta era precisamente lo que estaba buscando y la respuesta está incluida en la sección "Editar" –

Respuesta

6

Hay un error en la primavera de 3,1, se puede encontrar la respuesta en estas dos cuestiones:

Háganos saber si encuentra una solución para Spring 3.1, de lo contrario, debemos esperar hasta que 3.2 esté disponible. Tengo que decir que lo probé con Spring 3.2.0.M2 y todavía no funciona para mí.

+1

3.2.0.RC1 está por ahí y el error está solucionado. Se supone que también funciona en 3.2.0.M2, siempre y cuando anote sus clases de prueba con @WebAppConfiguration. –

7

Si @EnableWebMvc anotación requiere ServletContext entonces me sugieren para dividir su configuración a las definiciones habas que serán utilizados en las pruebas de unidad y la otra configuración que utilizan mediante la aplicación y el marco. En este caso, la aplicación importará ambas configuraciones y las pruebas unitarias solo importarán una.

BeansConfig.java:

@Configuration 
public class BeansConfig { 
    @Bean 
    MyBean myBean() { 
     return new MyBean() 
    } 
} 

WebConfig.java:

@Configuration 
@EnableWebMvc 
@Import(BeansConfig.class) 
public class WebConfig extends WebMvcConfigurationSupport {} 

TestFail.java:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes=BeansConfig.class) 
public class TestFail { 
    @Test 
    public void test() {} 
} 
+0

En realidad, eso es lo que estoy haciendo ahora. Me pregunto por qué falla la prueba unitaria. Estuvo bien cuando se configuró con XML en Spring 3.0. –

12

Como Guido mencionó anteriormente, esto se ha resuelto a partir de 3.2. Los siguientes son detalles de cómo aprovechar las nuevas mejoras de prueba. Para garantizar que un contexto de servlet se carga para su prueba, necesita anotar su prueba con @WebAppConfiguration y definir AnnotationConfigWebContextLoader como su contextual de carga, como a continuación:

@RunWith(SpringJUnit4ClassRunner.class)  
@WebAppConfiguration 
@ContextConfiguration(
    classes = MyWebConfig.class, 
    loader = AnnotationConfigWebContextLoader.class) 
public class MyTest { 
    //... 
} 
+0

¿Podría explicar cómo se carga el contexto de resorte de aplicación en estos casos de prueba? Aprecio que la clase MyWebConfig reemplace el archivo servlet-context.xml para inicializar la aplicación web, pero si nuestro controlador depende de otros beans para ser inyectados, ¿cómo se hace? En otros ejemplos, una 'location = classparth = context.xml' se pasa a ContextConfiguration. ¿Esto todavía es posible en el ejemplo anterior? – emeraldjava

+1

En la clase '@ Configuration'. Eso define qué classpaths deben escanearse para los beans anotados como '@ Component',' @ Controller', '@ Service', etc. También puede usar la anotación' Import' para importar un contexto XML. Puede crear clases '@ Configuration' específicamente para sus pruebas si lo desea. – Steve

+0

Gracias. En nuestra aplicación web real, tengo un ContextLoaderListener en el archivo web.xml que carga un contextConfigLocation = '/ WEB-INF/applicationContext.xml'. Para mi caso de prueba, creo que está sugiriendo que agregue la instrucción Importar a mi clase WebAppConfig, pero esto no significa que el contexto se cargue dos veces si la aplicación web real. Pude haber esperado que el código de clase de prueba hiciera algo para cargar el applicationContext.xml en lugar de la clase read config. – emeraldjava

Cuestiones relacionadas