22

Spring 3.1以降、 @ Enable *アノテーションのおかげで、JavaConfigをより簡単に使用できるようになりました。

そこで、WebConfigを作成してWebMvc構成を設定し、テストしてみました。しかし、WebConfigでWebMvcConfigurerAdapterまたはWebMvcConfigurationSupportを拡張すると、ServletContextがないため、単体テストが失敗します。コードとメッセージは次のようになります。

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

メッセージ

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

WebConfigを正しくユニットテストする方法は?

編集

ガルシアが言ったように、このバグはSpring3.2.0.RC1で修正されています。

テストクラスに@WebAppConfigurationアノテーションを追加するだけです。

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

4 に答える 4

12

Guido が以前に述べたように、これは 3.2 で解決されました。以下は、新しいテストの改善点を利用する方法の詳細です。テスト用にサーブレット コンテキストが確実にロードされるようにするには、以下のように、テストに注釈を付け、コンテキスト ローダーとして@WebAppConfiguration定義する必要があります。AnnotationConfigWebContextLoader

@RunWith(SpringJUnit4ClassRunner.class)    
@WebAppConfiguration
@ContextConfiguration(
    classes = MyWebConfig.class, 
    loader = AnnotationConfigWebContextLoader.class)
public class MyTest {
    //...
}
于 2014-01-09T13:38:44.003 に答える
7

@EnableWebMvc注釈が必要な場合ServletContextは、構成を単体テストで使用される Bean 定義と、アプリケーションとフレームワークで使用されるその他の構成に分割することをお勧めします。この場合、アプリケーションは両方の構成をインポートし、単体テストは 1 つだけをインポートします。

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() {}
}
于 2012-07-03T07:20:06.257 に答える
6

Spring 3.1にはバグがあり、次の2つの問題で答えを見つけることができます。

Spring 3.1の回避策を見つけた場合はお知らせください。そうでない場合は、3.2がリリースされるまで待つ必要があります。Spring 3.2.0.M2で試したばかりですが、まだ機能していません。

于 2012-10-17T22:28:07.417 に答える
2

もう 1 つの推奨事項は、spring-test-mvcを使用することです。これは、Controller テストが機能するためのモック サーブレット コンテキストを内部的に作成します。

アプローチを続行したい場合は、Mock サーブレット コンテキストを追加で初期化する独自の Spring Context ローダーを作成する必要がある場合があります 。 integration-testing-controllers/Spring-test-mvc ソースから

于 2012-07-03T11:13:20.053 に答える