Test endpointu z plikiem MultipartFile

Test endpointu z plikiem MultipartFile
SC
  • Rejestracja:ponad rok
  • Ostatnio:6 dni
  • Postów:19
0

Mam metodę w kontrolerze, która odbiera nowe dane do aktualizacji profilu użytkownika. W parametrze tej metody jest dto, który ma np. imię, nazwisko i zdjęcie profilowe, czyli MultipartFile.

Kopiuj
@PatchMapping("/settings/profile")
@ResponseStatus(HttpStatus.NO_CONTENT)
void updateUserProfile(@Valid @RequestBody AppUserProfileEditDTO userProfile) {
    appUserService.updateUserProfile(currentUserFacade.getCurrentUser(), userProfile);
}

Napisałem sobie taki test jak na screenie, w sekcji given robię zapis użytkownika do bazy danych i tworzę ten dto z nowymi danymi. Linia 281 wyrzuca wyjątek InvalidDefinitionException.

Kopiuj
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: pl.secret.iteventsapi.appuser.domain.dto.AppUserProfileEditDTO["profileImage"]->org.springframework.mock.web.MockMultipartFile["inputStream"])
Kopiuj
@Test
@Transactional
@WithMockUser(username = "jankowalski@example.com")
void shouldReturnUpdatedUserProfile() throws Exception {
    // given
    AppUser user = AppUserCreator.create("Jan", "Kowalski", imageRepository.save(ProfileImageCreator.createDefaultProfileImage()));
    appUserRepository.save(user);
    AppUserProfileEditDTO newUserProfileData = AppUserProfileEditDTOCreator.create(
            user,
            "Kraków",
            "Cześć!");
    // when
    MockHttpServletRequestBuilder request = MockMvcRequestBuilders
            .patch("/api/v1/settings/profile")
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(newUserProfileData));
    mockMvc.perform(request)
            .andDo(print())
            .andExpect(status().isNoContent());
    // then
    AppUser userAfterUpdate = appUserRepository.findById(user.getId()).get();
    assertThat(userAfterUpdate.getCity()).isEqualTo(newUserProfileData.getCity());
    assertThat(userAfterUpdate.getBio()).isEqualTo(newUserProfileData.getBio());
}

Wiem, że tutaj jest problem z serializacją pliku. Jak powinno się tworzyć takie dto w testach i jak napisać test dla takiej metody

edytowany 1x, ostatnio: Scarilt
Riddle
Zapoznaj się z Dlaczego nie należy zamieszczać kodu w postaci obrazków. Skopiuj kod, i wklej go w znacznikach ```.
SC
DA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około rok
0

Ciekawe jestem tego kodu, bo obawiam się, że zapis do DB dzieje się w kontrolerze

SC
  • Rejestracja:ponad rok
  • Ostatnio:6 dni
  • Postów:19
0

Jak w kontrolerze? AppUserService to serwis a nie repozytorium i dopiero w metodzie serwisowej robiony jest zapis do bazy danych.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Koszalin
  • Postów:10094
0

Dobe testy wyglądałyby jakoś tak:

Kopiuj
@Test
void shouldUpdateUserProfile() {
    // given
    var logged = user("Jan", "Kowalski", defaultImage());
    // when
    var response = request("/api/v1/settings/profile", profileEdit(logged, "Kraków", "Cześć"));
    // then
    assertResponseStatus(response, status().isNoContent());
}

@Test
void shouldGetUpdatedUserProfile() {
    // given
    var logged = user("Jan", "Kowalski", defaultImage());
    // when
    var response = request("/api/v1/settings/profile", profileEdit(logged, "Kraków", "Cześć"));
    // then
    var userData = userData("Jan", "Kowalski");
    assertEquals("Kraków", userData.getCity());
    assertEquals("Cześć!", userData.getBio());
}
szatkus1
  • Rejestracja:około 22 lata
  • Ostatnio:38 minut
0

JSON to nie multipart. Serializer się wywala, bo masz dane binarne, które bez specjalne konwersji nie wciśnie się do JSONa.

Do multipartów masz osobną metodę https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.html#multipart(java.lang.String,java.lang.Object...)

SC
  • Rejestracja:ponad rok
  • Ostatnio:6 dni
  • Postów:19
0

@Riddle rozumiem, że chodzi Ci o podzielenie tego testu na dwa osobne, pierwszy sprawdzi tylko czy aktualizacja wykonała się poprawnie poprzez sprawdzenie kodu odpowiedzi, a drugi pobierze tego użytkownika z bazy i sprawdzi zaktualizowane pola. Ok, dzięki za radę.

@szatkus1 znam tą metodę, ale nią można przetestować chyba tylko taki endpoint gdzie jest sam plik. A co do tej konwersji, masz na myśli przepuszczenie pliku przez Base64 i wysłanie jako Stringa?

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Koszalin
  • Postów:10094
0
Scarilt napisał(a):

@Riddle rozumiem, że chodzi Ci o podzielenie tego testu na dwa osobne, pierwszy sprawdzi tylko czy aktualizacja wykonała się poprawnie poprzez sprawdzenie kodu odpowiedzi, a drugi pobierze tego użytkownika z bazy i sprawdzi zaktualizowane pola. Ok, dzięki za radę.

Tak, oraz to żeby schować szczegóły testu, i uwidocznić rzeczy istotne.

SC
  • Rejestracja:ponad rok
  • Ostatnio:6 dni
  • Postów:19
0

oraz to żeby schować szczegóły testu, i uwidocznić rzeczy istotne.

Masz na myśli zapis użytkownika do bazy danych i tworzenie tego DTO z nowymi danymi?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.