Dans mes tests, j'ai configuré l'objet MockMvc
dans le @Before
comme ça
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity())
.build();
Dans chaque demande que je fais, j'ai toujours besoin d'envoyer les mêmes en-têtes. Existe-t-il un moyen de configurer les en-têtes que MockMvc
utilisera globalement ou par classe de test?
Que diriez-vous de faire une classe d'usine pour commencer avec votre demande déjà décroissante avec en-têtes? Étant donné que MockHttpServletRequestBuilder
est un générateur, il vous suffit de décorer la demande avec l'une des propriétés supplémentaires (paramètres, type de contenu, etc.) dont vous avez besoin. Le constructeur est conçu juste à cet effet! Par exemple:
public class MyTestRequestFactory {
public static MockHttpServletRequestBuilder myFactoryRequest(String url) {
return MockMvcRequestBuilders.get(url)
.header("myKey", "myValue")
.header("myKey2", "myValue2");
}
}
Puis dans votre test:
@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());
}
Chaque test appellera le noeud final avec les mêmes en-têtes.
Je ne sais pas si c'est toujours pertinent, mais je suis tombé sur le même problème. Nous avons ajouté une authentification par clé API à une REST api par la suite, et tous les tests (principalement avec @AutoConfigureMockMvc) devaient être ajustés à l'aide d'une API appropriée (en plus des nouveaux tests, testant que le les touches fonctionnent).
Spring utilise également leur modèle de personnalisateurs et de constructeurs lors de la création de MockMvc, comme cela se fait avec RestTemplateBuilder et RestTemplateCustomizer.
Vous pouvez créer un @ Bean/@ Component qui est un org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizer
et il sera récupéré pendant le processus bootstrap de vos @SpringBootTests.
Vous pouvez ensuite ajouter un parent DefaultRequetsBuilders qui est fusionné avec les RequestBuilders spécifiques lors de l'exécution du test.
Exemple de personnalisateur qui ajoute un en-tête
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);
}
}
J'espère que cela pourra aider.
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);
}
}
Définissez les propriétés de demande par défaut qui doivent être fusionnées dans toutes les demandes effectuées. En effet, cela fournit un mécanisme pour définir une initialisation commune pour toutes les demandes telles que le type de contenu, les paramètres de demande, les attributs de session et toute autre propriété de demande.
Vous pouvez écrire une implémentation de javax.servlet.Filter
. Dans votre cas, vous pouvez ajouter les en-têtes à votre demande. MockMvcBuilders
a une méthode pour ajouter des filtres:
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity())
.addFilter(new CustomFilter(), "/*")
.build();