[英]Why does Spring MockMvc result not contain a cookie?
我正在嘗試在我的REST API中對登錄和安全性進行單元測試,因此我嘗試盡可能接近地模擬現實生活中的請求序列。
我的第一個請求是:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).
addFilters(springSecurityFilterChain).build();
this.mapper = new ObjectMapper();
....
MvcResult result=mockMvc.perform(get("/login/csrf")).andExpect(status().is(200)).andReturn();
Cookie[] cookies = result.getResponse().getCookies();
(參見關於pastebin的完整課程)。
我嘗試在這里獲取cookie以便能夠使用收到的CSRF令牌登錄,但cookies
數組是空的!
但是,如果我運行我的應用程序並打電話
curl -i http://localhost:8080/login/csrf
我確實得到了一個Set-Cookie標頭,可以稍后使用該cookie(以及CSRF令牌)進行身份驗證。
所以問題是:我如何讓MockMvc向我返回一個cookie?
我找到了一種解決方法,使用從MockHttpServletRequest直接提取會話對象的能力:
session=(MockHttpSession)result.getRequest().getSession();
然后直接插入會話:
req.session(session);
我對此解決方案不滿意的原因是,如果模擬httpservlet在這方面的行為與真實的servlet不同,我怎么能確定它在其他情況下是否與真實的servlet相同。 所以我沒有測試應用程序本身,這可能會在測試中留下空白。
我使用RestTemplate進行cookie測試。 RestTemplate cookie處理程序
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(RestTemplateWithCookies.class)
public class ApplicationTest {
@LocalServerPort
private int port;
@Autowired
private Environment env;
@Autowired
private RestTemplateWithCookies restTemplate;
@Test
public void appTest() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.set("Referer", env.getProperty("allowed_referer"));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/scan?email=xxx@xxx.com", HttpMethod.GET, entity, String.class);
assertTrue(response.getStatusCode() == HttpStatus.FOUND);
HttpCookie c = restTemplate.getCoookies().stream().filter(x -> env.getProperty("server.session.cookie.name").equals(x.getName())).findAny().orElse(null);
assertTrue(c != null);
}
}
根據P.Péter的答案,制作了這個代碼片段,它將為mockMvc
上執行的每個請求( MockHttpServletRequestBuilder
)自動獲取並放回會話。
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private Filter springSecurityFilterChain;
@Before
public void setUp() throws Exception {
final MockHttpServletRequestBuilder defaultRequestBuilder = get("/dummy-path");
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
.defaultRequest(defaultRequestBuilder)
.alwaysDo(result -> setSessionBackOnRequestBuilder(defaultRequestBuilder, result.getRequest()))
.apply(springSecurity(springSecurityFilterChain))
.build();
}
private MockHttpServletRequest setSessionBackOnRequestBuilder(final MockHttpServletRequestBuilder requestBuilder,
final MockHttpServletRequest request) {
requestBuilder.session((MockHttpSession) request.getSession());
return request;
}
長期回答:檢查此解決方案(答案是針對春季4): 如何使用spring 3.2新mvc測試登錄用戶
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.