java 为什么使用 Spring 3.1 WebMvcConfig 进行单元测试失败?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11304999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:36:22  来源:igfitidea点击:

Why unit testing with Spring 3.1 WebMvcConfig fails?

javaspringspring-3

提问by Sanghyun Lee

From Spring 3.1, we can use JavaConfig more easily thanks to @Enable*annotations.

从 Spring 3.1 开始,由于@Enable*注释,我们可以更轻松地使用 JavaConfig 。

So I made a WebConfig to set WebMvc configuration, and tried to test it. But if I extends WebMvcConfigurerAdapter or WebMvcConfigurationSupport with WebConfig the unit test fails because of lack of ServletContext. The code and messages look like below.

所以我做了一个WebConfig来设置WebMvc的配置,并尝试进行测试。但是,如果我使用 WebConfig 扩展 WebMvcConfigurerAdapter 或 WebMvcConfigurationSupport,则由于缺少 ServletContext,单元测试失败。代码和消息如下所示。

WebConfig.java

配置文件

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurationSupport {}

Test.java

测试.java

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

Message

信息

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$bbfcca1.CGLIB$defaultServletHandlerMapping(<generated>)
    at com.zum.news.comments.web.WebConfig$$EnhancerByCGLIB$bbfcca1$$FastClassByCGLIB$b86ad0.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$bbfcca1.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

How to unit test the WebConfig properly?

如何正确地对 WebConfig 进行单元测试?

Edit

编辑

As Garcia said, this bug is fixed in Spring 3.2.0.RC1.

正如 Garcia 所说,此错误已在 Spring 3.2.0.RC1 中修复。

Just add @WebAppConfigurationannotation in the test class.

只需在测试类中添加@WebAppConfiguration注解即可。

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

采纳答案by Guido

There is a bug in Spring 3.1, you can find the answer in these two issues:

Spring 3.1有一个bug,你可以在这两个问题中找到答案:

Please let us know if you find a workaround for Spring 3.1, if not we must wait until 3.2 is out there. I have to say that I've just tried it with Spring 3.2.0.M2 and it is still not working for me.

如果您找到 Spring 3.1 的解决方法,请告诉我们,如果没有,我们必须等到 3.2 发布。我不得不说我刚刚用 Spring 3.2.0.M2 尝试过它,但它仍然不适合我。

回答by Steve

As Guido mentioned previously, this has been solved as of 3.2. The following are the details of how to take advantage of the new test improvements. To ensure that a servlet context is loaded for your test, you need to annotate your test with @WebAppConfigurationand define AnnotationConfigWebContextLoaderas your context loader, as below:

正如 Guido 之前提到的,这已经在 3.2 中解决了。以下是如何利用新测试改进的详细信息。为确保为您的测试加载 servlet 上下文,您需要使用上下文加载器注释测试@WebAppConfiguration并将其定义AnnotationConfigWebContextLoader为上下文加载器,如下所示:

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

回答by Slava Semushin

If @EnableWebMvcannotation require ServletContextthen I suggest to split your config to beans definitions which will be used in unit tests and other configuration which used by application and framework. In this case application will import both configs and unit tests will import only one.

如果@EnableWebMvc需要注释,ServletContext那么我建议将您的配置拆分为 bean 定义,这些定义将用于单元测试和应用程序和框架使用的其他配置。在这种情况下,应用程序将导入两个配置,而单元测试将只导入一个。

BeansConfig.java:

BeansConfig.java

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

WebConfig.java:

WebConfig.java

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

TestFail.java:

TestFail.java

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

回答by Biju Kunjummen

Another recommendation that I have would be to use spring-test-mvc, which internally creates a mock servlet context for the Controller tests to work.

我的另一个建议是使用spring-test-mvc,它在内部创建一个模拟 servlet 上下文,以便控制器测试工作。

If you want to continue with your approach, you may then have to create your own Spring Context loader that additionally initializes a Mock servlet context - along these lines: http://tedyoung.me/2011/02/14/spring-mvc-integration-testing-controllers/, From Spring-test-mvc source

如果你想继续你的方法,你可能需要创建你自己的 Spring Context 加载器,另外初始化一个 Mock servlet 上下文 - 沿着这些行:http: //tedyoung.me/2011/02/14/spring-mvc-集成测试控制器/,来自Spring-test-mvc 源