Cześć,
Chciałem napisać swój pierwszy test endpointu jednak po 2 dniach zmaganiach postanowiłem się poddać i napisać na forum :P
Do rzeczy.
Dostaję błąd jaki jest w załączniku. Z tego co próbowałem na różne sposoby go rozwiązać to nie odpala mi się metoda z adnotacją @BeforeAll albo występują inne dziwne błędy z obiektem MockMvc.
Chciałem koniecznie w taki sposób napisać ten test ( metoda która mi zamieni DTO na JSON i odwrotnie, principal ponieważ mam go w metodzie w kontrolerze, MockHttpServletResponse aby sprawdzić sobie przy okazji np. status) Różne inne próby innych konwersji json to java object kończyły się NPE z obiektu DTO więc podejrzewam, że ja w ogóle mogę źle te adnotację to testów rozumieć z tego wszystkiego...
Czekam na uwagi również pod kątem czy w taki sposób się to powinno robić ponieważ szukając informacji o testach jednostkowych znalazłem ogrom przeróżnych możliwości testowania więc wybrałem pierwszą lepszą z brzegu która wydawała mi się najbardziej ciekawa co do testowania akurat endpointów.
Klasa testowa:
import java.io.IOException;
import java.security.Principal;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@ExtendWith(MockitoExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ToDoListControllerTest {
@Mock
private Principal principal;
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@InjectMocks
private ToDoListController toDoListController;
@Mock
private ToDoListService toDoListService;
@Mock
private UserService userService;
@BeforeAll
void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(toDoListController).build();
}
private String mapToJson(Object obj) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
}
private <T> T mapFromJson(String json, Class<T> clazz)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, clazz);
}
@Test
public void toDoListCannotBeSavedWhenNameLengthIsInvalid() throws Exception {
// given
ToDoListDTO toDoListDTO = new ToDoListDTO();
toDoListDTO.setName("xd");
String inputJson = mapToJson(toDoListDTO);
given(principal.getName()).willReturn("user123");
// when
MockHttpServletResponse response = mockMvc.perform(post("/api/ToDoList/").principal(principal)
.contentType(MediaType.APPLICATION_JSON).content(inputJson).accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Then
assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST.value());
}
}
Klasa kontrolera:
@RestController
public class ToDoListController {
private ToDoListService toDoListService;
private UserService userService;
@Autowired
public ToDoListController(ToDoListService toDoListService, UserService userService) {
this.toDoListService = toDoListService;
this.userService = userService;
}
@RequestMapping(value = "/api/ToDoList", method = RequestMethod.POST)
public ResponseEntity<ToDoList> addNewList(Principal principal, @Valid @RequestBody ToDoListDTO todoListDTO,
BindingResult result) {
String username = principal.getName();
if (result.hasErrors()) {
List<FieldError> errors = result.getFieldErrors();
for (FieldError error : errors) {
System.out.println(error.getObjectName() + " " + error.getDefaultMessage());
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
User user = userService.getUserRepository().findByUsername(username);
ToDoList toDoList = new ToDoList();
toDoList.setName(todoListDTO.getName());
user.addToDoList(toDoList);
userService.getUserRepository().save(user);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
Klasa DTO
public class ToDoListDTO {
@NotEmpty
@Length(min = 3, max = 50)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}