web-dev-qa-db-ja.com

MockMvcはすべてのリクエストのヘッダーを設定します

私のテストでは、@BeforeMockMvcオブジェクトを次のように設定しました

mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .apply(springSecurity())
                .build();

すべてのリクエストで、常に同じヘッダーを送信する必要があります。 MockMvcがグローバルまたはテストクラスごとに使用するヘッダーを構成する方法はありますか?

6
isADon

すでにdecrorated-with-headersリクエストから始めるファクトリークラスを作成してみませんか? MockHttpServletRequestBuilderはビルダーなので、必要な追加のプロパティ(パラメーター、コンテンツタイプなど)でリクエストを装飾するだけです。ビルダーはこの目的のためだけに設計されています!例えば:

public class MyTestRequestFactory {

    public static MockHttpServletRequestBuilder myFactoryRequest(String url) {
        return MockMvcRequestBuilders.get(url)
                .header("myKey", "myValue")
                .header("myKey2", "myValue2");
    }
}

次に、テストで:

@Test
public void whenITestUrlWithFactoryRequest_thenStatusIsOK() throws Exception {

    mockMvc()
        .perform(MyTestRequestFactory.myFactoryRequest("/my/test/url"))
        .andExpect(status().isOk());
}

@Test
public void whenITestAnotherUrlWithFactoryRequest_thenStatusIsOK() throws Exception {

    mockMvc()
        .perform(MyTestRequestFactory.myFactoryRequest("/my/test/other/url"))
        .andExpect(status().isOk());
}

各テストは、同じヘッダーでエンドポイントを呼び出します。

5
Dovmo

それがまだ適切かどうかはわかりませんが、同じ問題に遭遇しました。その後、REST apiにAPIキー認証を追加しました。すべてのテスト(主に@AutoConfigureMockMvcを使用)は、適切なAPIを使用して調整する必要がありました(新しいテストの上に、キーが機能しています)。

Springは、RestTemplateBuilderとRestTemplateCustomizerで行われるように、MockMvcを作成するときにもカスタマイザとビルダーのパターンを使用します。

org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizerである@ Bean/@ Componentを作成することができ、@ SpringBootTestsのbootstrapプロセス中にピックアップされます。

次に、テストの実行時に特定のRequestBuilderとマージされる親defaultRequetsBuildersを追加できます。

ヘッダーを追加するサンプルカスタマイザ

package foobar;


import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizer;
import org.springframework.stereotype.Component;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;

/**
 * Whenever a mockmvc object is autoconfigured, this customizer should be picked up, and a default, usable, working, valid api key is set as
 * default authorization header to be applied on all tests if not overwritten.
 *
 */
@Component
public class ApiKeyHeaderMockMvcBuilderCustomizer implements MockMvcBuilderCustomizer {

    @Override
    public void customize(ConfigurableMockMvcBuilder<?> builder) {
        // setting the parent (mergeable) default requestbuilder to ConfigurableMockMvcBuilder
        // every specifically set value in the requestbuilder used in the test class will have priority over
        // the values set in the parent. 
        // This means, the url will always be replaced, since "any" would not make any sense.
        // In case of multi value properties (like headers), existing headers from our default builder they are either merged or appended,
        // exactly what we want to achieve
        // see https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcBuilderCustomizer.html
        // and https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/Mergeable.html
        RequestBuilder apiKeyRequestBuilder = MockMvcRequestBuilders.get("any")
            .header("api-key-header", "apikeyvalue");
        builder.defaultRequest(apiKeyRequestBuilder);
    }

}

お役に立てば幸いです。

4
BigDaddy
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(new HttpHeaderMockMvcConfigurer()).build();

public class HttpHeaderMockMvcConfigurer extends MockMvcConfigurerAdapter {
    @Override
    public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder, WebApplicationContext cxt) {
        builder.defaultRequest(MockMvcRequestBuilders.post("test").header("appId", "aaa"));
        return super.beforeMockMvcCreated(builder, cxt);
    }
}

実行されるすべてのリクエストにマージする必要があるデフォルトのリクエストプロパティを定義します。実際、これは、コンテンツタイプ、リクエストパラメータ、セッション属性、その他のリクエストプロパティなど、すべてのリクエストに共通の初期化を定義するメカニズムを提供します。

1
minjay26

javax.servlet.Filter 。あなたのケースでは、あなたのリクエストにヘッダーを追加することができます。 MockMvcBuildersにはフィルターを追加するメソッドがあります:

mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(springSecurity())
            .addFilter(new CustomFilter(), "/*")
            .build();
0
borino