2

I've created a test to try out my microservice. A simple get call that through 3 parameters returns me the message with the specifications of that user. I created it using Junit and Mockito. Below:

@Test
public void TestOk() throws Exception{
    CarsRequest carsRequest = new CarsRequest();
    carsRequest.setName(TestCostants.NAME);
    carsRequest.setPlate(TestCostants.PLATE);
    carsRequest.setPrice(TestCostants.PRICE);
    Cars car = new Cars("BMW","TG35647", "15000","re",80000000,
            null,null);
    List<Cars> cars = new ArrayList<>();
    cars.add(car);


    Mockito.when(
            service.getByPlate(carsRequest.getName(), carsRequest.getPlate(),
                    carsRequest.getPrice())).thenReturn(cars);
    RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
            "/resources/cars").accept(
            MediaType.APPLICATION_JSON).header("Authorization","Basic //myAuth");
    MvcResult result = mockMvc.perform(requestBuilder).andReturn();
    System.out.println(result.getResponse());


    String expected = "{\"name\"=\"BMW\", \"plate\"=\"TG35647\", " +
            "\"price\"=\"15000\",\"brand\"=\"re\", \"kilometers\"=\"80000000\", \"revisiondate\"=\"null\", \"owner\"=\"null\"}";
    JSONAssert.assertEquals(expected, result.getResponse()
            .getContentAsString(), false);
});

clearly the constants of the variables that are passed conform to those of the message that must return me. When I try to start the test it gives me an error This is the stacktrace I am reporting:

2021-03-29 12:45:07.906 [main] INFO  o.s.s.l.SpringSecurityLdapTemplate - Ignoring PartialResultException
{
  "@timestamp" : "2021-03-29T12:45:08.119+02:00",
  "@version" : "1",
  "message" : "[GET] http://localhost/resources/cars/ call resulted in the following error: Content type '' not supported",
  "logger_name" : "my.project.car.controller.ExceptionHandlingController",
  "thread_name" : "main",
  "level" : "ERROR",
  "level_value" : 40000
}
ErrorResponse: org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported
org.springframework.mock.web.MockHttpServletResponse@135f160e
MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /resources/cars/
       Parameters = {}
          Headers = [Accept:"application/json", Authorization:"Basic //myAuth"]
             Body = null
    Session Attrs = {}
Handler:
             Type = null
Async:
    Async started = false
     Async result = null
Resolved Exception:
             Type = org.springframework.web.HttpMediaTypeNotSupportedException
ModelAndView:
        View name = null
             View = null
            Model = null
FlashMap:
       Attributes = null
MockHttpServletResponse:
           Status = 500
    Error message = null
          Headers = [Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = application/json
             Body = {"esito":"KO","codiceEsito":"ERROR","descrizioneEsito":"Errore generico"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
java.lang.AssertionError:
Expected: name
     but none found
 ;
Expected: plate
     but none found
 ;
Expected: price
     but none found
 ;
Expected: brand
     but none found
 ;
Expected: kilometers
     but none found
 ;
Expected: revisiondate
     but none found
 ;
Expected: owner
     but none found
 ;

Trying to go to Debug, I get this error back, but I don't know how to handle it at all

Method threw 'org.mockito.exceptions.misusing.UnfinishedStubbingException' exception. Cannot evaluate my.project.service.CarService$MockitoMock$1824138024.toString()

I guess the two errors are related but I don't know how to fix this.

EDIT: As requested, I add my Car Service:

@Service
public class CarService {
    @Autowired
    CarRepository carRepository;
    @Autowired
    ObjectMapper objectMapper;

    public List<Car> getByPlate(String name, String plate, String price) throws JsonProcessingException {
        List<Car> car = new ArrayList<>();
        for (Cache.Entry<String, Car> entry: carRepository.findAllByNameAndPlateAndPrice(name, plate,price)){
            car.add(new Car(entry.getKey(), entry.getValue()));
            System.out.println("Entry: " + objectMapper.writeValueAsString(entry));
        }
        return cars;
    }
}

and my CarController

@RestController
@RequestMapping("/resources/")
public class CarController {
    @Autowired
    CarService carService;
    @Autowired
    ObjectMapper objectMapper;
    @GetMapping(
    value = "/cars",
    consumes = {MediaType.APPLICATION_JSON_VALUE},
    produces = {MediaType.APPLICATION_JSON_VALUE})
    public CarsResponse getCars(@RequestBody CarsRequest request) throws IOException {
        //some code
    }
Numero 21
  • 245
  • 5
  • 17
  • Most likely the endpoint has required parameters (name, plate, price) but you provided none in your request. Please show us the method under test in the controller. – Lesiak Mar 29 '21 at 12:53
  • Why are you sending parameters to get request in a RequestBody? Although this is not the source of the problem (missing body in the request is) I would advise reconsidering the signature of this method before writing a test to cast this behaviour in cement. – Lesiak Mar 31 '21 at 17:46
  • Is this a `mockMvc` test? . It looks like to me, then it may not load your service classes, it only loads the slice of `controller` class in context. How are you mocking your service class in test? – code_mechanic Apr 05 '21 at 06:06
  • Please add complete test class how it looks. – code_mechanic Apr 06 '21 at 03:15

1 Answers1

4

First of all, using GET requests with a body is the poor practice. Use POST requests instead.

Then, spring tells you about org.springframework.web.HttpMediaTypeNotSupportedException and in your controller method getCars() you describe the next:

    consumes = {MediaType.APPLICATION_JSON_VALUE},
    produces = {MediaType.APPLICATION_JSON_VALUE}

But in your test you don't specify any content-type:

RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
        "/resources/cars").accept(
        MediaType.APPLICATION_JSON).header("Authorization","Basic //myAuth");

Try to add content-type .contentType(MediaType.APPLICATION_JSON):

 RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/resources/cars")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Authorization", "Basic //myAuth");

Also, I don't see how you pass the body to the request. Try to add it .content(mapper.writeValueAsString(carsRequest)):

 RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/resources/cars")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Authorization", "Basic //myAuth")
                .content(mapper.writeValueAsString(carsRequest));

where mapper is ObjectMapper. I assume you are using com.fasterxml.jackson.databind.ObjectMapper.

Volodya Lombrozo
  • 2,325
  • 2
  • 16
  • 34