Возможно ли тестирование защищенных контроллеров Spring с Mock Mvc? - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь выяснить, как лучше всего протестировать конфигурацию безопасности моего приложения Spring Boot. Моя цель - провести два теста:

  • Для пользователя A, Доступ к ресурсам / результатам теста в 401
  • Для пользователя B, Доступ к ресурсам / результатам теста в 200

Когда я начал свои исследования, все учебники, которые я обнаружил, указывали на «Макет Mvc», но я не смог написать 2 теста, которые работали бы таким образом. Почти во всех случаях мне показалось, что Безопасность была полностью проигнорирована (Макет Mvc вернул 200 даже без указания пользователя).

Допустим, у меня есть следующая настройка, как простая пример:

Конфигурация безопасности:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }

}

Контроллер:

@RestController
public class TestController {

    @GetMapping("/test")
    public String getTest() {
        return "hello";
    }

}

Свойства:

spring.security.user.name=testuser
spring.security.user.password=testpassword

Я мог успешно проверить это с помощью "TestRestTemplate "вот так:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    void when_userIsValid_should_return200() throws Exception {
        String res = testRestTemplate
                .withBasicAuth("testuser", "testpassword")
                .getForEntity("/test", String.class)
                .getBody();
        Assert.assertEquals("hello", res);
    }

    @Test
    void when_userIsInvalid_should_return401() throws Exception {
        HttpStatus res = testRestTemplate
                .withBasicAuth("foo", "bar")
                .getForEntity("/test", String.class)
                .getStatusCode();
        Assert.assertEquals(HttpStatus.UNAUTHORIZED, res);
    }

}

Итак, мой вопрос: это" путь к go "? Если Mock Mvc является инструментом выбора, не могли бы вы привести рабочий пример? Я испробовал 30 решений из Tutorials и Stackoverflow, и ни одно из них не сработало (либо Mock Mvc null, Безопасность полностью игнорировалась, Controller Method больше не обнаруживался, и я просто слишком глуп, чтобы заставить их работать: /)

Заранее спасибо!

1 Ответ

1 голос
/ 31 января 2020

вы можете использовать WebMvcTest для инициализации только слоя Controller (он не будет создавать / внедрять все другие bean-компоненты Spring, определяющие службу / репозиторий и т. Д. c ..), но он подходит (и быстрее) при тестировании контроллера logi c.

Вот пример

@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MainController.class)
public class ControllerTest  {

@Autowired
private MockMvc mockMvc;

//@MockBean
//Service service; // mock service dependencies if needed

@Test
public void invalidCredentials() throws Exception {

    this.mockMvc
            .perform(get("/test").header(HttpHeaders.AUTHORIZATION,
                    "Basic " + Base64Utils.encodeToString("testuser:WRONGpassword".getBytes())))
            .andExpect(status().isOk());
}
...