2012-07-03 18 views
22

Od wiosny 3.1 możemy łatwiej używać JavaConfig dzięki adnotacjom @Enable*.Dlaczego testowanie urządzenia przy użyciu Spring 3.1 WebMvcConfig nie działa?

Zrobiłem WebConfig, aby ustawić konfigurację WebMvc i próbowałem ją przetestować. Ale jeśli rozszerzam WebMvcConfigurerAdapter lub WebMvcConfigurationSupport z WebConfig, test jednostki kończy się niepowodzeniem z powodu braku ServletContext. Kod i wiadomości wyglądają jak poniżej.

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() {} 
} 

Wiadomość

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 

Jak przetestować urządzenie z webconfig prawidłowo?

Edit

Jak powiedział Garcia, ten problem został rozwiązany w Spring 3.2.0.RC1.

Po prostu dodaj adnotację @WebAppConfiguration do klasy testowej.

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

ja nie rozumiem, jak ta kwestia ma tak mało głosów. Przypuszczam, że są ludzie, którzy próbują przeprowadzić testy integracyjne z wiosenną 3.1 niceties ... –

+1

Pytanie było dokładnie tym, czego szukałem, a odpowiedź jest zawarta w sekcji "Edycja" –

Odpowiedz

6

Jest to błąd wiosną 3.1 można znaleźć odpowiedź w tych dwóch kwestiach:

Daj nam znać, jeśli znajdziesz obejście dla Spring 3.1, jeśli nie, musimy poczekać, aż pojawi się 3.2. Muszę powiedzieć, że właśnie wypróbowałem to z Spring 3.2.0.M2 i nadal nie działa dla mnie.

+1

3.2.0.RC1 jest tam i naprawiono błąd. Ma działać również w wersji 3.2.0.M2, o ile dodasz do swoich klas testowych @WebAppConfiguration. –

7

Jeśli @EnableWebMvc adnotacja wymagają ServletContext to proponuję podzielić swój config fasola definicji, które będą używane w testach jednostkowych i innych konfiguracji, które używane przez aplikację i ram. W takim przypadku aplikacja zaimportuje obie konfiguracje, a testy jednostkowe zaimportują tylko jeden.

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

Właściwie to właśnie robię teraz. Zastanawiam się, dlaczego test jednostkowy nie powiedzie się. Było dobrze, gdy skonfigurowano XML w Spring 3.0. –

12

Jak wspomniano wcześniej, Guido zostało rozwiązane od wersji 3.2. Poniżej przedstawiono szczegóły dotyczące korzystania z nowych ulepszeń testowych. Aby upewnić się, że kontekst aplet jest ładowany do testu, trzeba opisywać test z @WebAppConfiguration i zdefiniować AnnotationConfigWebContextLoader jako ładowacza kontekstowego, jak poniżej:

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

Czy możesz wyjaśnić, kto jest kontekstem sprężyny aplikacji jest ładowany w tych przypadkach testowych. Doceniam, że klasa MyWebConfig zastępuje plik servlet-context.xml w celu zainicjowania aplikacji internetowej, ale jeśli nasz kontroler jest zależny od innych ziaren, które mają zostać wstrzyknięte, jak to się robi. W innych przykładach "location = classparth = context.xml" jest przekazywany do ContextConfiguration - czy jest to nadal możliwe w powyższym przykładzie? – emeraldjava

+1

W klasie '@ Configuration'. To określa, jakie ścieżki klas powinny być skanowane w przypadku fasoli opisywanych jako '@ Component',' @ Controller', '@ Service' itp. Może również użyć adnotacji' Import' do importowania kontekstu XML. Jeśli chcesz, możesz utworzyć klasy "@ Configuration" przeznaczone specjalnie do testów. – Steve

+0

Dzięki. W naszej prawdziwej aplikacji internetowej mam ContextLoaderListener w pliku web.xml, który ładuje contextConfigLocation = '/ WEB-INF/applicationContext.xml'. W moim przypadku testowym sugeruję dodanie instrukcji Import do mojej klasy WebAppConfig, ale nie oznacza to, że kontekst jest ładowany dwukrotnie, jeśli jest to prawdziwa aplikacja internetowa. Być może oczekiwałam, że kod klasy testowej zrobi coś, aby załadować plik applicationContext.xml zamiast klasy read read. – emeraldjava

Powiązane problemy