Модульное тестирование контроллера с использованием @WebMvcTest не работает, когда контроллер зависит от контекста запроса - PullRequest
0 голосов
/ 28 декабря 2018

Я выполняю модульный тест для моего контроллера, используя @WebMvcTest в моем модульном тесте.Мой контроллер извлекает RequestAttributes данные из RequestContextHolder:

RequestContextHolder.currentRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_REQUEST)

Данные, хранящиеся здесь, устанавливаются в перехватчике:

RequestAttributes reqAttr = RequestContextHolder.currentRequestAttributes();
reqAttr.setAttribute(name, value, RequestAttributes.SCOPE_REQUEST);
RequestContextHolder.setRequestAttributes(reqAttr, true);

В моем тесте модуля контроллера перехватчик не являетсявыполняется, поэтому я попытался установить атрибуты запроса перед запуском теста, но я получаю эту ошибку:

java.lang.IllegalStateException: запрос с привязкой к потоку не найден: Вы ссылаетесь на атрибуты запроса внефактический веб-запрос или обработка запроса вне изначально полученного потока?Если вы действительно работаете в веб-запросе и по-прежнему получаете это сообщение, ваш код, вероятно, выполняется за пределами DispatcherServlet: в этом случае используйте RequestContextListener или RequestContextFilter для предоставления текущего запроса.

Я пыталсяэтот ответ https://stackoverflow.com/a/9419859/5545327. Я добавил:

@Mock
private RequestAttributes attrs;

@Before
public void before() {
    MockitoAnnotations.initMocks(this);
    RequestContextHolder.setRequestAttributes(attrs);
}

@Test
public void testController() {
    when(requestAttributes.getAttribute(eq("<attribute name>"),
        eq(RequestAttributes.SCOPE_REQUEST))).thenReturn(<mockReturn>);
    // do your test...
}

Но это не работает.Ошибка исчезла, но контроллер получает значение null от RequestContextHolder.Кстати, я проверяю свой контроллер, выполняя это:

mockMvc.perform(post("<url>").content("<post params here>")).andExpect(status().isOk());

, где mockMvc от @WebMvcTest.

Примечание: У меня другой классдля тестирования интеграции, поэтому я использую @WebMvcTest здесь вместо @SpringBootTest

Я надеюсь, что вы можете дать описательный ответ, так как я также совсем новичок в Spring.

Спасибо!

Редактировать:

  • Я не могу просто поместить данные в фактический атрибут HttpRequest.Если я не ошибаюсь, атрибуты HttpRequest не добавляются автоматически в качестве атрибута запроса в RequestContextHolder.Кроме того, мне нужны данные не из HttpRequest, а из HttpRequest.И я издеваюсь над ним, так как знаю фактический запрос, так как это мой модульный тест.

Код выглядит так:

@RunWith(SpringRunner.class)
@WebMvcTest
@OverrideAutoConfiguration(enabled = true)
@ActiveProfiles("test")
public abstract class BaseControllerTest {
    @Autowired
    protected MockMvc mockMvc;
}

public class ControllerTest extends BaseControllerTest {
    @Test
    public void testControllerMethod() {
        mockMvc.perform(post("<url>").content("<post params here>")).andExpect(status().isOk());
        // some more codes here
    }
}

public class Controller {
    @PostMapping
    public String controllerMethod() {
        // some more codes here
        Object myObject = RequestContextHolder.currentRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_REQUEST);
        // some more codes here
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...