Browse Source

Support placeholder values in Spring MVC Test

Issue: SPR-10825
pull/338/merge
Rossen Stoyanchev 13 years ago
parent
commit
c211c98b40
  1. 70
      spring-test-mvc/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java
  2. 64
      spring-test-mvc/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java

70
spring-test-mvc/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java

@ -19,9 +19,12 @@ package org.springframework.test.web.servlet.setup; @@ -19,9 +19,12 @@ package org.springframework.test.web.servlet.setup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.format.support.DefaultFormattingConversionService;
@ -30,6 +33,9 @@ import org.springframework.http.converter.HttpMessageConverter; @@ -30,6 +33,9 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.mock.web.MockServletContext;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.util.StringValueResolver;
import org.springframework.validation.Validator;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.context.WebApplicationContext;
@ -110,6 +116,8 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -110,6 +116,8 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
private Boolean removeSemicolonContent;
private Map<String, String> placeHolderValues = new HashMap<String, String>();
/**
* Protected constructor. Not intended for direct instantiation.
@ -282,10 +290,23 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -282,10 +290,23 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
* if provided, is in turn set on
* {@link AbstractHandlerMapping#setRemoveSemicolonContent(boolean)}.
*/
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
public StandaloneMockMvcBuilder setRemoveSemicolonContent(boolean removeSemicolonContent) {
this.removeSemicolonContent = removeSemicolonContent;
return this;
}
/**
* In a standalone setup there is no support for placeholder values embedded in
* request mappings. This method allows manually provided placeholder values so they
* can be resolved. Alternatively consider creating a test that initializes a
* {@link WebApplicationContext}.
*/
public StandaloneMockMvcBuilder addPlaceHolderValues(String name, String value) {
this.placeHolderValues.put(name, value);
return this;
}
@Override
protected void initWebAppContext(WebApplicationContext cxt) {
StubWebApplicationContext mockCxt = (StubWebApplicationContext) cxt;
@ -295,20 +316,19 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -295,20 +316,19 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
private void registerMvcSingletons(StubWebApplicationContext cxt) {
StandaloneConfiguration configuration = new StandaloneConfiguration();
StandaloneConfiguration config = new StandaloneConfiguration();
RequestMappingHandlerMapping handlerMapping = configuration.requestMappingHandlerMapping();
handlerMapping.setServletContext(cxt.getServletContext());
handlerMapping.setApplicationContext(cxt);
cxt.addBean("requestMappingHandlerMapping", handlerMapping);
StaticRequestMappingHandlerMapping hm = config.getHandlerMapping(cxt);
hm.registerHandlers(controllers);
cxt.addBean("requestMappingHandlerMapping", hm);
RequestMappingHandlerAdapter handlerAdapter = configuration.requestMappingHandlerAdapter();
RequestMappingHandlerAdapter handlerAdapter = config.requestMappingHandlerAdapter();
handlerAdapter.setServletContext(cxt.getServletContext());
handlerAdapter.setApplicationContext(cxt);
handlerAdapter.afterPropertiesSet();
cxt.addBean("requestMappingHandlerAdapter", handlerAdapter);
cxt.addBean("handlerExceptionResolver", configuration.handlerExceptionResolver());
cxt.addBean("handlerExceptionResolver", config.handlerExceptionResolver());
cxt.addBeans(initViewResolvers(cxt));
cxt.addBean(DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME, this.localeResolver);
@ -337,12 +357,13 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -337,12 +357,13 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
/** Using the MVC Java configuration as the starting point for the "standalone" setup */
private class StandaloneConfiguration extends WebMvcConfigurationSupport {
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
StaticRequestMappingHandlerMapping handlerMapping = new StaticRequestMappingHandlerMapping();
handlerMapping.registerHandlers(controllers);
public StaticRequestMappingHandlerMapping getHandlerMapping(StubWebApplicationContext cxt) {
StaticRequestMappingHandlerMapping handlerMapping = new StaticRequestMappingHandlerMapping();
handlerMapping.setServletContext(cxt.getServletContext());
handlerMapping.setApplicationContext(cxt);
handlerMapping.setEmbeddedValueResolver(new StaticStringValueResolver(placeHolderValues));
handlerMapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
handlerMapping.setUseTrailingSlashMatch(useTrailingSlashPatternMatch);
handlerMapping.setOrder(0);
@ -351,7 +372,6 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -351,7 +372,6 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
if (removeSemicolonContent != null) {
handlerMapping.setRemoveSemicolonContent(removeSemicolonContent);
}
return handlerMapping;
}
@ -427,6 +447,30 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo @@ -427,6 +447,30 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
}
}
/** A static resolver placeholder for values embedded in request mappings */
private static class StaticStringValueResolver implements StringValueResolver {
private final PropertyPlaceholderHelper helper;
private final PlaceholderResolver resolver;
public StaticStringValueResolver(final Map<String, String> values) {
this.helper = new PropertyPlaceholderHelper("${", "}", ":", false);
this.resolver = new PlaceholderResolver() {
@Override
public String resolvePlaceholder(String placeholderName) {
return values.get(placeholderName);
}
};
}
@Override
public String resolveStringValue(String strVal) throws BeansException {
return this.helper.replacePlaceholders(strVal, this.resolver);
}
}
/** A {@link ViewResolver} that always returns same View */
private static class StaticViewResolver implements ViewResolver {

64
spring-test-mvc/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.servlet.setup;
import org.junit.Test;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import static org.junit.Assert.*;
/**
* @author Rossen Stoyanchev
*/
public class StandaloneMockMvcBuilderTests {
// SPR-10825
@Test
public void placeHoldersInRequestMapping() throws Exception {
StubWebApplicationContext cxt = new StubWebApplicationContext(new MockServletContext());
StandaloneMockMvcBuilder builder = new StandaloneMockMvcBuilder(new PlaceholderController());
builder.addPlaceHolderValues("sys.login.ajax", "/foo");
builder.initWebAppContext(cxt);
RequestMappingHandlerMapping hm = cxt.getBean(RequestMappingHandlerMapping.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
HandlerExecutionChain chain = hm.getHandler(request);
assertNotNull(chain);
assertEquals("handleWithPlaceholders", ((HandlerMethod) chain.getHandler()).getMethod().getName());
}
@Controller
private static class PlaceholderController {
@RequestMapping(value = "${sys.login.ajax}")
private void handleWithPlaceholders() { }
}
}
Loading…
Cancel
Save