19

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の完全なクラスを参照してください)。

後で受け取った CSRF トークンでログインできるように、ここで Cookie を取得しようとしましたが、cookies配列が空です!

ただし、アプリケーションを実行して呼び出すと

curl -i http://localhost:8080/login/csrf

Set-Cookie ヘッダーを取得し、後でその Cookie (および CSRF トークン) を使用して認証できます。

問題は、MockMvc に Cookie を返してもらうにはどうすればよいかということです。

4

3 に答える 3

13

MockHttpServletRequest からセッション オブジェクトを直接抽出する機能を使用して、回避策を見つけました。

session=(MockHttpSession)result.getRequest().getSession();

そして後でセッションを直接挿入します:

req.session(session);

私がこの解決策に満足していない理由は、この点でモック httpservlet が実際のサーブレットとは異なる動作をする場合、他の場合に実際のサーブレットと同じように動作するかどうかをどのように確認できるかということです。したがって、アプリケーション自体をテストしていないため、テストにギャップが生じる可能性があります。

于 2014-10-09T15:10:40.993 に答える
1

Cookie を使用したテストのために RestTemplate を使用しています。 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);

    }

}
于 2017-09-13T19:42:59.160 に答える