在我的测试中,我在MockMvc
中设置@Before
对象
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity())
.build();
在我做的每个请求中,我总是需要发送相同的标题。
有没有办法配置MockMvc
将在全局或每个测试类中使用的标头?
答案 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
定义应合并到所有已执行请求中的默认请求属性。实际上,这提供了一种机制,用于定义所有请求的通用初始化,例如内容类型,请求参数,会话属性和任何其他请求属性。