Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for OPTIONS request in the MVC test framework #205

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -43,11 +43,12 @@ public abstract class MockMvcBuilderSupport {

protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers) {
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers, Boolean dispatchOptions) {

ServletContext servletContext = webAppContext.getServletContext();

TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
dispatcherServlet.setDispatchOptionsRequest(dispatchOptions);
try {
dispatcherServlet.init(servletConfig);
}
Expand Down
Expand Up @@ -79,6 +79,17 @@ public static MockHttpServletRequestBuilder put(String urlTemplate, Object... ur
public static MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) {
return new MockHttpServletRequestBuilder(HttpMethod.DELETE, urlTemplate, urlVariables);
}

/**
* Create a {@link MockHttpServletRequestBuilder} for a OPTIONS request.
*
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param urlVariables zero or more URL variables
*/
public static MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables) {
return new MockHttpServletRequestBuilder(HttpMethod.OPTIONS, urlTemplate, urlVariables);
}


/**
* Create a {@link MockHttpServletRequestBuilder} for a request with the given HTTP method.
Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
* An concrete implementation of {@link MockMvcBuilder} with methods for
Expand All @@ -53,6 +54,8 @@ public class DefaultMockMvcBuilder<Self extends MockMvcBuilder> extends MockMvcB
private final List<ResultMatcher> globalResultMatchers = new ArrayList<ResultMatcher>();

private final List<ResultHandler> globalResultHandlers = new ArrayList<ResultHandler>();

private Boolean dispatchOptions = Boolean.FALSE;


/**
Expand Down Expand Up @@ -177,6 +180,17 @@ public final <T extends Self> T alwaysDo(ResultHandler resultHandler) {
this.globalResultHandlers.add(resultHandler);
return (T) this;
}

/**
* Should the {@link DispatcherServlet} dispatch OPTIONS request to controllers.
* @param dispatchOptions
* @see {@link DispatcherServlet#setDispatchOptionsRequest(boolean)}
*/
@SuppressWarnings("unchecked")
public final <T extends Self> T dispatchOptions(boolean dispatchOptions) {
this.dispatchOptions = dispatchOptions;
return (T) this;
}

/**
* Build a {@link MockMvc} instance.
Expand All @@ -191,7 +205,7 @@ public final MockMvc build() {
Filter[] filterArray = this.filters.toArray(new Filter[this.filters.size()]);

return super.createMockMvc(filterArray, mockServletConfig, this.webAppContext,
this.defaultRequestBuilder, this.globalResultMatchers, this.globalResultHandlers);
this.defaultRequestBuilder, this.globalResultMatchers, this.globalResultHandlers,this.dispatchOptions);
}

/**
Expand Down
@@ -0,0 +1,81 @@
/**
*
*/
package org.springframework.test.web.servlet;

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

import java.util.concurrent.atomic.AtomicInteger;

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.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.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;

/**
* Tests for SPR-10093 (support for OPTIONS requests).
* @author Arnaud Cogoluègnes
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class Spr10093Tests {

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

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

@Test
public void test() throws Exception {
MyController controller = wac.getBean(MyController.class);
int initialCount = controller.counter.get();
this.mockMvc.perform(options("/myUrl")).andExpect(status().isOk());
Assert.assertEquals(initialCount+1,controller.counter.get());
}


@Configuration
@EnableWebMvc
static class WebConfig extends WebMvcConfigurerAdapter {

@Bean
public MyController myController() {
return new MyController();
}
}

@Controller
private static class MyController {

private AtomicInteger counter = new AtomicInteger(0);

@RequestMapping(value="/myUrl",method=RequestMethod.OPTIONS)
@ResponseBody
public void handle() {
counter.incrementAndGet();
}
}


}