Я пытаюсь выполнить модульное тестирование класса контроллера в своем весеннем приложении. Я очень борюсь с этим тестом. Я хочу протестировать свой контроллер как с точки зрения функциональности метода, так и с точки зрения аутентификации И авторизации.
Проблема не в функциональности, а в авторизации и аутентификации. Поскольку я хочу выполнить тест UNIT, я не хочу аннотировать свой тестовый класс с помощью @SpringBootTest, поскольку это загружает весь контекст приложения (если я не ошибаюсь). Поэтому я решил использовать @WebMvcTest, который добавляет безопасности, и моя первая проблема в том, что он не принимает во внимание роли. У меня есть URL-адреса, защищенные ролями, и @WebMvcTest, похоже, не заботится о них. Кроме того, после тестирования всех моих защищенных URL-адресов я решил проверить свои общедоступные URL-адреса и написал свои тесты без какой-либо проверки, что привело к ошибке 401. После этого я понял, что все мои другие тесты проходили случайно, поскольку на самом деле все URL-адреса были защищены, а не те, которые я установил в своем классе конфигурации безопасности.
Прочитав онлайн, я обнаружил, что могу включить свой класс конфигурации безопасности как часть аннотации @ContextConfiguration. Единственная проблема заключается в том, что тесты не запускаются, поскольку контекст приложения не может быть загружен. Причина в том, что класс конфигурации безопасности содержит некоторые переменные, помеченные @Autowired. Я начал включать @MockBean и соответствующий bean-компонент в свой тестовый класс, и одна за другой ошибки начали меняться, пока, наконец, не был загружен контекст приложения. Мне это не нравится, поскольку ни один из примеров, которые я нашел в Интернете, не делал этого, и кажется грязным иметь в моем тесте просто случайные переменные, чтобы угодить классу конфигурации.
Я действительно застрял и искал часами, но у меня ничего не работало. Я просто хочу проверить свои конечные точки на функциональность, авторизацию и аутентификацию, используя мой класс конфигурации, а не какой-то класс по умолчанию, который использует Spring.
Однако у меня есть вопрос, в котором я не уверен, и, возможно, мне ответит кто-нибудь более опытный. Выходит ли проверка авторизации и аутентификации за рамки модульного тестирования? Нужно ли мне загружать весь контекст приложения с помощью @SpringBootTest?
Это фрагмент моего тестового класса с аннотациями и тем, как я готовлю MockMvc:
@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class)
@ContextConfiguration(classes = {MyController.class,SecurityConfig.class})
public class MyControllerTest {
@Autowired
private MockMvc mockMvc;
}
Мой класс контроллера помечен @Restcontroller, и ни один из методов не имеет @PreAuthorize или @PostAuthorize, они просто полагаются на файл конфигурации безопасности. При тестировании вручную (вызовы API через POSTMAN) все работает как надо, поэтому я уверен, что это проблема с тестовой конфигурацией с моей стороны.
Это мой класс конфигурации безопасности (фрагмент):
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
@Order(3)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ClassA classA;
@Autowired
private ClassB classB;
@Autowired
private ClassC classC;
...
.antMatchers("/public/**").permitAll()
}
Это тест, который продолжает возвращать 401, хотя я знаю, что он должен вернуть 200:
@Test
public void testGetIsProductionValue() throws Exception {
MvcResult result = mockMvc.perform(get("/public/production")
.param("production", "false"))
.andExpect(status().isOk())
.andReturn();
}
См. github.com/spring-projects/spring-boot/issues/6514 и stackoverflow.com/questions/38675020/….
Спасибо за ваш ответ! Прочитав это, я пришел к выводу, что для проверки безопасности я напишу отдельный интеграционный тест.




что еще в вашем фрагменте?