WebAppConfiguration in Spring Tests – Spring测试中的WebAppConfiguration

最后修改: 2016年 8月 24日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’ll explore the @WebAppConfiguration annotation in Spring, why we need it in our integration tests and also how can we configure it so that these tests actually bootstrap a WebApplicationContext.

在这篇文章中,我们将探讨Spring中的@WebAppConfiguration注解,为什么我们在集成测试中需要它,以及我们如何配置它,使这些测试真正引导一个WebApplicationContext

2. @WebAppConfiguration

2.@WebAppConfiguration

Simply put, this is a class-level annotation used to create a web version of the application context in the Spring Framework.

简单地说,这是一个类级注解,用于在Spring框架中创建Web版本的应用程序上下文。

It’s used to denote that the ApplicationContext which is bootstrapped for the test should be an instance of WebApplicationContext.

它用于表示为测试而引导的ApplicationContext应该是WebApplicationContext的一个实例。

A quick note about usage – we’ll usually find this annotation in integration tests because the WebApplicationContext is used to build a MockMvc object. You can find more information about integration testing with Spring here.

关于用法的简短说明 – 我们通常会在集成测试中发现这个注解,因为WebApplicationContext被用来构建MockMvc对象。您可以在这里找到有关Spring集成测试的更多信息。

3. Loading a WebApplicationContext

3.加载一个WebApplicationContext

Starting with Spring 3.2, there is now support for loading a WebApplicationContext in integration tests:

从Spring 3.2开始,现在支持在集成测试中加载WebApplicationContext

@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeControllerTest {
    ...
}

This instructs the TestContext framework that a WebApplicationContext should be loaded for the test.

这指示TestContext框架,WebApplicationContext应该为测试加载。

And, in the background a MockServletContext is created and supplied to our test’s WebApplicationContext by the TestContext framework.

而且,在后台,一个MockServletContext被创建并由TestContext框架提供给我们测试的WebApplicationContext

3.1. Configuration Options

3.1.配置选项

By default, the base resource path for the WebApplicationContext will be set to “file:src/main/webapp”, which is the default location for the root of the WAR in a Maven Project.

默认情况下,WebApplicationContext的基础资源路径将被设置为“file:src/main/webapp”,这是Maven项目中WAR根目录的默认位置。

However, we can override this by simply providing an alternate path to the @WebAppConfiguration annotation:

然而,我们可以通过简单地提供一个替代路径给@WebAppConfiguration注解来覆盖这一点。

@WebAppConfiguration("src/test/webapp")

We can also reference a base resource path from the classpath instead of the file system:

我们也可以从classpath而不是文件系统中引用一个基本的资源路径。

@WebAppConfiguration("classpath:test-web-resources")

3.2. Caching

3.2.缓存

Once the WebApplicationContext is loaded it will be cached and reused for all subsequent tests that declare the same unique context configuration within the same test suite.

一旦WebApplicationContext被加载,它将被缓存并重用于所有后续的测试,这些测试在同一测试套件中声明了相同的独特上下文配置。

For further details on caching, you can consult the Context caching section of the reference manual.

有关缓存的进一步详情,您可以查阅参考手册中的上下文缓存部分。

4. Using @WebAppConfiguration in Tests

4.在测试中使用@WebAppConfiguration

Now that we understand why do we need to add the @WebAppConfiguration annotation in our test classes, let’s see what happens if we miss adding it when we are using a WebApplicationContext.

现在我们明白了为什么我们需要在测试类中添加@WebAppConfigurationannotation,让我们看看如果我们在使用WebApplicationContext时错过了添加它,会发生什么。

@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTest {

    @Autowired
    private WebApplicationContext webAppContext;
    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
    }
    
    ...
}

Notice that we commented out the annotation to simulate the scenario in which we forget to add it. Here it’s easy to see why the test will fail when we run the JUnit test: we are trying to autowire the WebApplicationContext in a class where we haven’t set one.

注意,我们注释了注解,以模拟我们忘记添加注解的情况。在这里,我们很容易看出为什么当我们运行JUnit测试时,测试会失败。我们试图在一个没有设置WebApplicationContext的类中自动连接WebApplicationContext

A more typical example however is a test that uses a web-enabled Spring configuration; that’s actually enough to make the test break.

然而,一个更典型的例子是,一个使用支持网络的Spring配置的测试;这实际上足以使测试中断。

Let’s have a look:

让我们看一看。

@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTestWithoutMockMvc {

    @Autowired
    private EmployeeController employeeController;

    ...
}

Even though the above example isn’t autowiring a WebApplicationContext it will still fail because it’s trying to use a web-enabled configuration – WebConfig:

即使上面的例子没有自动连接WebApplicationContext,它仍然会失败,因为它试图使用一个支持网络的配置 – WebConfig

@Configuration
@EnableWebMvc
@ComponentScan("com.baeldung.web")
public class WebConfig implements WebMvcConfigurer {
    ...
}

The annotation @EnableWebMvc is the culprit here – that will basically require a web enabled Spring context, and without it – we’ll see the test fail:

注解@EnableWebMvc是这里的罪魁祸首–这基本上需要一个支持Web的Spring上下文,如果没有它,我们将看到测试失败。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
  No qualifying bean of type [javax.servlet.ServletContext] found for dependency: 
    expected at least 1 bean which qualifies as autowire candidate for this dependency. 

Dependency annotations: 
  {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at o.s.b.f.s.DefaultListableBeanFactory
      .raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
    at o.s.b.f.s.DefaultListableBeanFactory
      .doResolveDependency(DefaultListableBeanFactory.java:1119)
    at o.s.b.f.s.DefaultListableBeanFactory
      .resolveDependency(DefaultListableBeanFactory.java:1014)
    at o.s.b.f.a.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
      .inject(AutowiredAnnotationBeanPostProcessor.java:545)
    ... 43 more

So that’s the problem that we’re easily fixing by adding the @WebAppConfiguration annotation to our tests.

所以这就是我们通过在测试中添加@WebAppConfiguration注解来轻松解决的问题。

5. Conclusion

5.结论

In this article we showed how we can let the TestContext framework to load a WebApplicationContext into our integration tests just by adding the annotation.

在这篇文章中,我们展示了如何让TestContext框架加载一个WebApplicationContext到我们的集成测试中,只需添加注解。

Finally, we looked at the examples that even though if we add the @ContextConfiguration to the test, this won’t be able to work unless we add the @WebAppConfiguration annotation.

最后,我们看了一些例子,即使我们在测试中添加了@ContextConfiguration,除非我们添加@WebAppConfiguration注解,否则这将无法工作。

The implementation of the examples in this article are available in our repository on GitHub.

本文中的示例的实现可在我们在GitHub的存储库中获得。