2016-12-02 9 views
3

Spring RESTコントローラでリソースを作成した後、次のようにヘッダ内の位置を返します。ユニットテストSpring RESTコントローラの 'Location'ヘッダ

@RequestMapping(..., method = RequestMethod.POST) 
public ResponseEntity<Void> createResource(..., UriComponentsBuilder ucb) { 

    ... 

    URI locationUri = ucb.path("/the/resources/") 
     .path(someId) 
     .build() 
     .toUri(); 

    return ResponseEntity.created(locationUri).build(); 
} 

ユニットテストでは、次のように位置を確認しています。

@Test 
public void testCreateResource(...) { 
    ... 
    MockHttpServletRequestBuilder request = post("...") 
     .content(...) 
     .contentType(MediaType.APPLICATION_JSON) 
     .accept(MediaType.APPLICATION_JSON); 

    request.session(sessionMocked); 

    mvc.perform(request) 
     .andExpect(status().isCreated()) 
     .andExpect(header().string("Location", "/the/resources" + id); 
} 

この結果は次のメッセージで失敗します。

java.lang.AssertionError: Response header Location expected:</the/resources/123456> but was:<http://localhost/the/resources/123456> 

Iを見込んでLocationヘッダのコンテキストプレフィックスhttp://localhostを提供しなければならないように思えます。

  • コンテキストをハードコードするのは安全ですか?もしそうなら、なぜですか?
  • もしそうでなければ、テストケースのために正しく生成する正しい方法は何ですか?
  • 答えて

    1

    レスポンスのLocationヘッダーに完全なURIを持つ必要がない場合(つまり、要件、設計制約など...):相対URIを使用するように切り替えることを検討します(HTTP標準の観点から有効です) - [1]参照:https://tools.ietf.org/html/rfc7231)相対URIは、最新のブラウザとライブラリでサポートされている提案された標準です。これにより、エンドポイントの動作をテストし、長期的には脆弱にならないようにします。

    あなたは完全なパスをアサートする必要がある場合は、MockMvcを使用しているので、あなたは正確に何をしたいのテスト要求にURIを設定することができます。

    @Autowired 
    private WebApplicationContext webApplicationContext; 
    
    @Test 
    public void testCreateResource() { 
        MockMvc mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
        mvc.perform(MockMvcRequestBuilders.get(new URI("http://testserver/the/resources"))); 
    

    これは、注入されたビルダープロデュース」http://testserverを行います"ビルドが呼び出されたとき。注意してください。将来のフレームワークの変更により、このテスト動作を削除すると頭痛を引き起こす可能性があります。

    2

    URIを構築するのにUriComponentsBuilderを使用しているため、あなたのロケーションヘッダーにホスト名が設定されていると思います。ちょうどnew URI("/the/resources")のようなものを使っていたら、あなたのテストは合格したでしょう。あなたのケースでは

    、私はリダイレクトURLを一致させるためにredirectedUrlPatternを使用したい:あなたはローカルホストをハードコーディングする必要はありませんので

    .andExpect(redirectedUrlPattern("http://*/the/resources"))

    これは、任意のホスト名と一致します。 AntPathMatcherhereで使用できるさまざまなパターンの詳細をご覧ください。

    +0

    解決策は、リダイレクト動作をテストします。 OPは、場所ヘッダーをテストしたかった。 今日まで、私は 'redirectedUrlPattern'について知りませんでした –

    関連する問題