Testowanie metody PUT jako niezautoryzowany użytkownik

0

Próbuję napisać test dla metody PUT, który sprawdzi czy zostanie zwrócony błąd 401 Unauthorized kiedy niezautoryzowany użytkownik wyśle zapytanie. Ta metoda sendRequestAsUnauthorizedUser() robi JSON'a z przekazanego obiektu i nie dodaje header'u Authorization.

@Test
void shouldReturnErrorWhenUnauthorizedUserUpdatesHisProfileData() {
    // given
    AppUserProfileEditDTO newProfileData = createNewProfileData(
            "Testowy", "Użytkownik", "2000-01-01", "Testy Wielkie", "Testowy biogram"
    );
    // when
    ResponseEntity<Map<String, String>> response = restTemplate.exchange(
            "/api/v1/users/me/profile",
            PUT,
            sendRequestAsUnauthorizedUser(newProfileData),
            new ParameterizedTypeReference<>() {}
    );
    // then
    assertThat(response.getStatusCode()).isEqualTo(UNAUTHORIZED);
}

Przy odpalaniu testu dostaję taki wyjątek:

org.springframework.web.client.ResourceAccessException: I/O error on PUT request for "http://localhost:59495/api/v1/users/me/profile": cannot retry due to server authentication, in streaming mode; nested exception is java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode

Jak przekazuję null zamiast wywoływania tej metody sendRequestAsUnauthorizedUser() to leci ten sam wyjątek. Co robię nie tak i jak poprawnie napisać taki test?

1

W internatach znalazłem coś takiego:
https://github.com/spring-attic/spring-security-oauth/issues/441#issuecomment-92033542

tam to co prawda jest to w kontekście oauth ale problem z restTemplate jest raczej ten sam.

Więc myśle ze najlepszym wyjściem jest to po prostu przepisać na mockmvc.

0

@MckMaciek właśnie nie chciałem używać MockMvc, tylko zwykłego klienta HTTP, ale teraz sprawdziłem z MockMvc i test się wykonał poprawnie. Czemu w takim razie MockMvc jest odradzane skoro zwykły klient HTTP nie daje sobie rady z takimi prostymi testami?

0

Użyj sobie WebTestClienta

0

@Nofenak sprawdziłem właśnie i mam pytanie - czy można w jakiś lepszy sposób zmapować odpowiedź na mapę niż to co ja zrobiłem poniżej?

    @Test
    void shouldReturnErrorWhenUserWithGivenEmailExists() throws IOException {
        // given
        var newUserData = createNewUserData(
                "Patryk", "Kowalski", "2000-01-01", "qwerty", "qwerty"
        );
        // when
        EntityExchangeResult<byte[]> response = webTestClient.post()
                .uri("/api/v1/register")
                .body(Mono.just(newUserData), CreateUserDTO.class)
                .accept(APPLICATION_JSON)
                .exchange()
                .expectBody()
                .returnResult();
        Map<String, List<String>> body = objectMapper.readValue(response.getResponseBody(), new TypeReference<>() {});
        // then
        assertThat(response.getStatus()).isEqualTo(BAD_REQUEST);
        assertThat(response.getResponseBody()).isNotNull();
        assertThat(body.size()).isEqualTo(1);
        assertThat(body.get("email").get(0)).isEqualTo("{form.field.email.error.emailIsInUse.message}");
    }
0

@Scarilt A dlaczego chcesz to mapować na jakieś mapy z listami? Zmapuj sobię w returnResult na jakąś klasę User albo UserDto. ObjectMapper nie będzie potrzebny

0

A cos takiego nie możesz
.exchange().expectStatus().isOk().expectBody().json(Response.jsonData);
Tylko zmień status i odpowiedz.

0

@Nofenak bo w przypadku wystąpienia błędu zwracam mapę, gdzie kluczem jest nazwa pola, a wartością lista błędów dla tego pola.
@bbzzyyczczeek przyjrzę się temu później, ale widzę, że musiałbym do .json przekazać oczekiwanego Stringa, czyli w tym przypadku zrobić Stringa z mapy.

0

A jakiej odpowiedzi oczekujesz?
I takie moje spostrzeżenie jeśli oczekujesz 401 Unauthorized to czemu
a w asercji sprawdzasz assertThat(response.getStatus()).isEqualTo(BAD_REQUEST);

0

@bbzzyyczczeek napisałem w poście wyżej - mapy, gdzie kluczem jest nazwa pola, a wartością lista błędów dla tego pola, czyli w tym przypadku będzie tylko jeden błąd. Ten drugi fragment kodu to jest inny test, nie ten co w pierwszym poście.

1 użytkowników online, w tym zalogowanych: 0, gości: 1