MockMvc настраивает заголовок для всех запросов - PullRequest
0 голосов
/ 25 мая 2018

В моих тестах я настраивал объект MockMvc в @Before следующим образом

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

В каждом моем запросе мне всегда нужно отправлять одни и те же заголовки.Есть ли способ настроить заголовки, которые MockMvc будет использовать глобально или для каждого класса тестирования?

Ответы [ 4 ]

0 голосов
/ 22 августа 2019
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);
    }
}

Определение свойств запроса по умолчанию, которые должны быть объединены со всеми выполненными запросами.По сути, это обеспечивает механизм для определения общей инициализации для всех запросов, таких как тип контента, параметры запроса, атрибуты сеанса и любое другое свойство запроса.

0 голосов
/ 26 мая 2018

Вы можете написать реализацию javax.servlet.Filter.В вашем случае вы можете добавить заголовки в ваш запрос.MockMvcBuilders имеет метод для добавления фильтров:

mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(springSecurity())
            .addFilter(new CustomFilter(), "/*")
            .build();
0 голосов
/ 29 ноября 2018

Не знаю, актуально ли это, но я наткнулся на ту же проблему.После этого мы добавили аутентификацию по ключу API в API REST, и все тесты (в основном с @AutoConfigureMockMvc) необходимо было скорректировать с использованием надлежащего API (поверх новых тестов, проверяющих работоспособность ключей).

Spring использует шаблон Customizer и Builders также при создании MockMvc, как это делается с RestTemplateBuilder и RestTemplateCustomizer.

Вы можете создать компонент @ Bean / @, который является org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizer, и он будетполучить в процессе начальной загрузки ваших @ SpringBootTests.

Затем вы можете добавить родительский defaultRequetsBuilders, который объединяется с конкретными RequestBuilders при запуске теста.

Образец Customizer, который добавляет заголовок

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

}

Надеюсь, что поможет.

0 голосов
/ 25 мая 2018

Как насчет того, чтобы создать заводской класс, чтобы начать работу с уже обработанным запросом с заголовками?Поскольку 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());
}

Каждый тест вызывает конечную точку с одинаковыми заголовками.

...