Spring @WebAppConfiguration Annotation Example

Spring @WebAppConfiguration Annotation Example
We will use spring @WebAppConfiguration annotation to test the web controllers. @WebAppConfiguration is a class-level annotation that will load web specific ApplicationContext, that is, WebApplicationContext. In this article we will show you how to inject WebApplicationContext and run integration tests.
The default path to the root of the web application is src/main/webapp. One may override it by passing a different path to the @WebAppConfiguration.

@WebAppConfiguration must be used in conjunction with @ContextConfiguration.
In the below test class, we load WebApplicationContext and MockServletContext using the @WebAppConfiguration annotation and inject their instances using @Autowired.
In test testGetRequest(), we run a request which in turn calls the controller method and then print the response.

SpringWebAppConfigurationExample:

package com.javarticles.spring;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

import java.net.URI;

import javax.servlet.ServletContext;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletContext;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.util.UriComponentsBuilder;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class SpringWebAppConfigurationExample {
    @Autowired
    protected WebApplicationContext wac;

    @Autowired
    protected MockServletContext mockServletContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = webAppContextSetup(this.wac).build();
    }

    @Test
    public void verifyWac() {
        ServletContext servletContext = wac.getServletContext();
        Assert.assertNotNull(servletContext);
        Assert.assertTrue(servletContext instanceof MockServletContext);
        for (String beanName : wac.getBeanDefinitionNames()) {
            if (beanName.contains("springCustomContextConfigurationExample")) {
                System.out.println("Bean Name: " + beanName);
                System.out.println("Bean " + wac.getBean(beanName));
            }
        }
    }

    @Test
    public void testGetRequest() throws Exception {
        String id = "hello";
        URI url = UriComponentsBuilder.fromUriString("/greet").pathSegment(id)
                .build().encode().toUri();
        System.out.println("Call " + url + ", result: " + 
                mockMvc.perform(get(url)).andReturn().getResponse().getContentAsString());
        mockMvc.perform(get(url)).andExpect(status().isOk())
                .andExpect(content().string("hello world"));
    }

    @Configuration
    @EnableWebMvc
    static class WebConfig extends WebMvcConfigurerAdapter {

        @Bean
        public GreetController greetController() {
            return new GreetController();
        }
    }

    @Controller
    private static class GreetController {

        @RequestMapping(value = "/greet/{id}", method = RequestMethod.GET)
        @ResponseBody
        public String getCircuit(@PathVariable String id) {
            return id + " world";
        }
    }
}

Output:

Feb 10, 2016 11:22:31 PM org.springframework.test.context.support.AbstractContextLoader generateDefaultLocations
INFO: Could not detect default resource locations for test class [com.javarticles.spring.SpringCustomContextConfigurationExample]: no resource found for suffixes {-context.xml}.
Feb 10, 2016 11:22:31 PM org.springframework.test.context.support.AbstractDelegatingSmartContextLoader processContextConfiguration
INFO: AnnotationConfigWebContextLoader detected default configuration classes for context configuration [ContextConfigurationAttributes@1ef7fe8e declaringClass = 'com.javarticles.spring.SpringCustomContextConfigurationExample', classes = '{class com.javarticles.spring.SpringCustomContextConfigurationExample$WebConfig}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader'].
Feb 10, 2016 11:22:31 PM org.springframework.test.context.web.WebTestContextBootstrapper getDefaultTestExecutionListenerClassNames
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
Feb 10, 2016 11:22:31 PM org.springframework.test.context.web.WebTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
Feb 10, 2016 11:22:31 PM org.springframework.test.context.web.WebTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
Feb 10, 2016 11:22:31 PM org.springframework.test.context.web.WebTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@6bdf28bb, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@6b71769e, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2752f6e2, org.springframework.test.context.support.DirtiesContextTestExecutionListener@e580929]
Feb 10, 2016 11:22:31 PM org.springframework.web.context.support.GenericWebApplicationContext prepareRefresh
INFO: Refreshing org.springframework.web.context.support.GenericWebApplicationContext@15975490: startup date [Wed Feb 10 23:22:31 IST 2016]; root of context hierarchy
Feb 10, 2016 11:22:31 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/greet/{id}],methods=[GET]}" onto public java.lang.String com.javarticles.spring.SpringCustomContextConfigurationExample$MyController.getCircuit(java.lang.String)
Feb 10, 2016 11:22:31 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@15975490: startup date [Wed Feb 10 23:22:31 IST 2016]; root of context hierarchy
Feb 10, 2016 11:22:31 PM org.springframework.mock.web.MockServletContext log
INFO: Initializing Spring FrameworkServlet ''
Feb 10, 2016 11:22:31 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization started
Feb 10, 2016 11:22:31 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization completed in 11 ms
Bean Name: springCustomContextConfigurationExample.WebConfig
Bean com.javarticles.spring.SpringCustomContextConfigurationExample$WebConfig$$EnhancerBySpringCGLIB$$d5d005a7@50eac852
Feb 10, 2016 11:22:31 PM org.springframework.mock.web.MockServletContext log
INFO: Initializing Spring FrameworkServlet ''
Feb 10, 2016 11:22:31 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization started
Feb 10, 2016 11:22:31 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization completed in 1 ms
Call /greet/hello, result: hello world
Feb 10, 2016 11:22:31 PM org.springframework.web.context.support.GenericWebApplicationContext doClose
INFO: Closing org.springframework.web.context.support.GenericWebApplicationContext@15975490: startup date [Wed Feb 10 23:22:31 IST 2016]; root of context hierarchy
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@67e21ea2 testClass = com.xymzsfxy.backend.service.PriceCrawlerServiceTest, locations = [], classes = [com.xymzsfxy.backend.BackendApplication, com.xymzsfxy.backend.service.PriceCrawlerServiceTest.TestConfig], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["crawler.sources.source1=https://example.com/price?id=%s", "crawler.selectors.source1=div.price", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [[ImportsContextCustomizer@2184962c key = [@org.apiguardian.api.API(consumers={"*"}, since="5.0", status=STABLE), @org.springframework.test.context.TestPropertySource(inheritLocations=true, inheritProperties=true, locations={}, properties={"crawler.sources.source1=https://example.com/price?id=%s", "crawler.selectors.source1=div.price"}, value={}), @org.springframework.scheduling.annotation.EnableAsync(annotation=java.lang.annotation.Annotation.class, mode=PROXY, order=2147483647, proxyTargetClass=false), @org.springframework.boot.test.context.SpringBootTest(args={}, classes={}, properties={}, useMainMethod=NEVER, value={}, webEnvironment=MOCK), @org.springframework.context.annotation.Import({org.springframework.scheduling.annotation.AsyncConfigurationSelector.class}), @org.springframework.test.context.BootstrapWith(org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class)]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@537f60bf, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@229c6181, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@eb9e61c5, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5b1669c0, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4b013c76, org.springframework.boot.test.context.SpringBootTestAnnotation@af687362], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCach
最新发布
03-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值