提交 f5d2b88e 编写于 作者: R Rossen Stoyanchev

"sharedHttpSession" shortcut for MockMvc builders

Issue: SPR-13820
上级 1d35c7c5
......@@ -122,6 +122,13 @@ public interface ConfigurableMockMvcBuilder<B extends ConfigurableMockMvcBuilder
/**
* Add a {@code MockMvcConfigurer} that automates MockMvc setup and
* configures it for some specific purpose (e.g. security).
*
* <p>There is a built-in {@link SharedHttpSessionConfigurer} that can be
* used to re-use the HTTP session across requests. 3rd party frameworks
* like Spring Security also use this mechanism to provide configuration
* shortcuts.
*
* @see SharedHttpSessionConfigurer
*/
<T extends B> T apply(MockMvcConfigurer configurer);
......
/*
* Copyright 2002-2017 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 javax.servlet.http.HttpSession;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link MockMvcConfigurer} that stores and re-uses the HTTP session across
* multiple requests performed through the same {@code MockMvc} instance.
*
* <p>Example use:
* <pre class="code">
* import static org.springframework.test.web.servlet.setup.SharedHttpSessionConfigurer.sharedHttpSession;
*
* // ...
*
* MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
* .apply(sharedHttpSession())
* .build();
*
* // Use mockMvc to perform requests ...
* </pre>
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class SharedHttpSessionConfigurer implements MockMvcConfigurer {
private HttpSession session;
@Override
public void afterConfigurerAdded(ConfigurableMockMvcBuilder<?> builder) {
builder.alwaysDo(result -> this.session = result.getRequest().getSession(false));
}
@Override
public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder,
WebApplicationContext context) {
return request -> {
if (this.session != null) {
request.setSession(this.session);
}
return request;
};
}
public static SharedHttpSessionConfigurer sharedHttpSession() {
return new SharedHttpSessionConfigurer();
}
}
/*
* Copyright 2002-2017 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 javax.servlet.http.HttpSession;
import org.junit.Test;
import org.springframework.stereotype.Controller;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.bind.annotation.GetMapping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.SharedHttpSessionConfigurer.sharedHttpSession;
/**
* Tests for {@link SharedHttpSessionConfigurer}.
* @author Rossen Stoyanchev
*/
public class SharedHttpSessionTests {
@Test
public void httpSession() throws Exception {
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
.apply(sharedHttpSession())
.build();
String url = "/session";
MvcResult result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
HttpSession session = result.getRequest().getSession(false);
assertNotNull(session);
assertEquals(1, session.getAttribute("counter"));
result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
session = result.getRequest().getSession(false);
assertNotNull(session);
assertEquals(2, session.getAttribute("counter"));
result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
session = result.getRequest().getSession(false);
assertNotNull(session);
assertEquals(3, session.getAttribute("counter"));
}
@Test
public void noHttpSession() throws Exception {
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
.apply(sharedHttpSession())
.build();
String url = "/no-session";
MvcResult result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
HttpSession session = result.getRequest().getSession(false);
assertNull(session);
result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
session = result.getRequest().getSession(false);
assertNull(session);
url = "/session";
result = mockMvc.perform(get(url)).andExpect(status().isOk()).andReturn();
session = result.getRequest().getSession(false);
assertNotNull(session);
assertEquals(1, session.getAttribute("counter"));
}
@Controller
private static class TestController {
@GetMapping("/session")
public String handle(HttpSession session) {
Integer counter = (Integer) session.getAttribute("counter");
session.setAttribute("counter", (counter != null ? counter + 1 : 1));
return "view";
}
@GetMapping("/no-session")
public String handle() {
return "view";
}
}
}
......@@ -3822,7 +3822,7 @@ IntelliJ) may not require any additional configuration. Just check the support f
completion on static members.
[[spring-mvc-test-server-setup-options]]
===== Setup Options
===== Setup Choices
There are two main options for creating an instance of `MockMvc`.
The first is to load Spring MVC configuration through the __TestContext
framework__, which loads the Spring configuration and injects a `WebApplicationContext`
......@@ -3927,6 +3927,48 @@ answer. However, using the "standaloneSetup" does imply the need for additional
Alternatively, you may choose to write all tests with "webAppContextSetup" in order to
always test against your actual Spring MVC configuration.
[[spring-mvc-test-server-setup-steps]]
===== Setup Features
No matter which MockMvc builder you use all `MockMvcBuilder` implementations provide
some common and very useful features. For example you can declare an `Accept` header
for all requests and expect a status of 200 as well as a `Content-Type` header
in all responses as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
// static import of MockMvcBuilders.standaloneSetup
MockMVc mockMvc = standaloneSetup(new MusicController())
.defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
.build();
----
In addition 3rd party frameworks (and applications) may pre-package setup
instructions like the ones through a `MockMvcConfigurer`. The Spring Framework
has one such built-in implementation that helps to save and re-use the HTTP
session across requests. It can be used as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
// static import of SharedHttpSessionConfigurer.sharedHttpSession
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
.apply(sharedHttpSession())
.build();
// Use mockMvc to perform requests...
----
See `ConfigurableMockMvcBuilder` for a list of all MockMvc builder features
or use the IDE to explore the available options.
[[spring-mvc-test-server-performing-requests]]
===== Performing Requests
It's easy to perform requests using any HTTP method:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册