MockMvc为所有请求配置标头

时间:2018-05-25 15:47:50

标签: spring spring-test mockmvc

在我的测试中,我在MockMvc中设置@Before对象

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

在我做的每个请求中,我总是需要发送相同的标题。 有没有办法配置MockMvc将在全局或每个测试类中使用的标头?

4 个答案:

答案 0 :(得分:3)

如果您已经使用已经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());
}

每个测试都会使用相同的标题调用端点。

答案 1 :(得分:2)

我不知道它是否仍然有用,但是我偶然发现了同样的问题。 之后,我们向REST api添加了API密钥身份验证,并且所有测试(主要使用@AutoConfigureMockMvc)都需要使用适当的API进行调整(在新测试之上,测试密钥是否正常工作)。

Spring在创建MockMvc时也会使用其Customizers and Builders模式,就像使用RestTemplateBuilder和RestTemplateCustomizer一样。

您可以创建一个org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizer的@ Bean / @ Component,它将在您的@SpringBootTests的引导过程中被拾取。

然后您可以添加一个父defaultRequetsBuilders,在运行测试时将其与特定的RequestBuilders合并。

添加标题的示例定制程序

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);
    }

}

希望有帮助。

答案 2 :(得分:0)

您可以编写javax.servlet.Filter的实现。在您的情况下,您可以将标题添加到您的请求中。 MockMvcBuilders有一种添加过滤器的方法:

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

答案 3 :(得分:0)

willSet

定义应合并到所有已执行请求中的默认请求属性。实际上,这提供了一种机制,用于定义所有请求的通用初始化,例如内容类型,请求参数,会话属性和任何其他请求属性。