Tentando testar esse método da classe: AddressResource, caso houver uma exception.
@RestController
@RequestMapping("api/addresses")
public class AddressResource {
private final DatabaseAccessManager<Address> service;
public AddressResource(DatabaseAccessManager<Address> service) { this.service = service; }
@GetMapping("/get/{id}")
public ResponseEntity<Address> findById(@PathVariable Long id){
return ResponseEntity.status(HttpStatus.OK).body(service.findById(id));
}
Mas aponta teste não sucedido e ainda o erro: java.lang.AssertionError: Status expected:<404> but was:<200>
package com.viegasb.webapi.resource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.viegasb.webapi.entities.Address;
import com.viegasb.webapi.exceptions.GlobalExceptionHandler;
import com.viegasb.webapi.exceptions.services.EntityNotFoundException;
import com.viegasb.webapi.services.DatabaseAccessManager;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
@ExtendWith(MockitoExtension.class)
public class AddressResourceTest {
private Address address;
private @Autowired MockMvc mockMvc;
private @InjectMocks AddressResource resource;
private @Mock DatabaseAccessManager<Address> database;
@BeforeEach
public void setup() {
address = new Address(1L, "Los Angeles", "California", "South Park", "984726-94");
mockMvc = MockMvcBuilders.standaloneSetup(resource)
.build();
}
@Test
public void shouldFindExistingId() throws Exception {
when(database.findById(address.getId()))
.thenReturn(address);
mockMvc.perform(MockMvcRequestBuilders.get("/api/addresses/get/{id}", address.getId()))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(address.getId()))
.andReturn();
verify(database).findById(address.getId());
verifyNoMoreInteractions(database);
}
@Test
public void shouldReturnNotFoundForNonExistingId() throws Exception {
when(database.findById(address.getId()))
.thenReturn(address);
when(database.findById(2L))
.thenThrow(new EntityNotFoundException(address.getId()));
mockMvc.perform(MockMvcRequestBuilders.get("/api/addresses/get/{id}", address.getId()))
.andExpect(MockMvcResultMatchers.status().isNotFound())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
verify(database).findById(address.getId());
verifyNoMoreInteractions(database);
}
}
não sei qual o correto seria em informar a classe de exceção personalizada ou a classe que trata as exceptions do resource:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<StandardError> entityNotFound(EntityNotFoundException e, HttpServletRequest request) {
var error = new StandardError(HttpStatus.NOT_FOUND.value(),e.getMessage(),request.getRequestURI());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}