簡體   English   中英

為什么Spring MockMvc結果不包含cookie?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM