Kong / unirest-java

Unirest in Java: Simplified, lightweight HTTP client library.
http://kong.github.io/unirest-java/
MIT License
2.59k stars 593 forks source link

Writing test cases for Unirest java #371

Closed shakyasudeep closed 3 years ago

shakyasudeep commented 3 years ago

I have used Unirest library for calling third party APIs in my services,it works fine but fails when writing test cases. But I also need to test the Service classes which calls the third party APIs, I have tried to test the services but it usually fails. How to test a service that uses Unirest library to call the APIs ? I am usingSpring Bootand posting my code of the service and the test cases.

Service class method :

private String locationUrl = "https://data.sfgov.org/resource/rqzj-sfat.json";

    @Override
    public List<FoodTruckDto> listFoodTruckLocations(Double givenLatitude, Double givenLongitude) throws Exception{

        log.info("Given Latitude => "+givenLatitude+" Given Longitude => "+givenLongitude);

        List<FoodTruckDto> foodTrucks = new ArrayList<>();      

        HttpResponse<List<FoodTruckDto>> foodTrucksResponse =
                Unirest.get(locationUrl) .queryString("facilitytype", "Truck") .asObject(new
                        GenericType<List<FoodTruckDto>>(){});

        if (foodTrucksResponse.getStatus() == HttpStatus.OK) {

            foodTrucks = foodTrucksResponse.getBody();

            foodTrucks.sort(new SortingLocations(givenLatitude, givenLongitude));

        } else {            
            UnirestParsingException ex = foodTrucksResponse.getParsingError().get();
            log.error("Error Message => "+ex.getMessage());
            log.error("Error Cause => "+ex.getCause());
            log.error("Error Original Body => "+ex.getOriginalBody()); 

            throw new CustomException("exc001"); 
        }
        return foodTrucks;
    }

Test class method :


@SpringBootTest
public class LocationServiceImplTest {

    @Mock
    private RestTemplate restTemplate;

    private MockRestServiceServer mockServer;

    @MockBean
    private LocationService locationService;

    @BeforeEach
    public void setUp() {

        mockServer = MockRestServiceServer.createServer(restTemplate);

    }

    /**
     * Test of listFoodTruckLocations method, of class LocationServiceImpl.
     */
    @Test
    public void testListFoodTruckLocations() throws Exception {

        Gson gson = new Gson();

        List<FoodTruckDto> foodTruckResult = new ArrayList<>();

        this.mockServer.expect(requestTo("https://data.sfgov.org/resource/rqzj-sfat.json?facilitytype=Truck"))
        .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(gson.toJson(foodTruckResult)));                         

        List<FoodTruckDto> foodTruckDtos = locationService.listFoodTruckLocations(233.3, -131.02);

        mockServer.verify();    

        assertThat(foodTruckDtos).isEqualTo(foodTruckResult);
    }

}

The test case fails at mockServer.verify();. Is using RestTemplate wrong idea for testing Unirest? Or is there anything wrong in my code ? Please suggest how to move forward. Is there any separate library to test Unirest based services ? @ryber @subnetmarco

ryber commented 3 years ago

Hi, @shakyasudeep Spring MockRestServiceServer is a great tool, but it only works with Spring RestTemplate. It binds itself to the insides of a RestTemplate instance and intercepts the calls. It's never going to work with Unirest (or Apache Client, or Feign, or etc)

It's a little weird you would post this today because this last weekend we released as part of Unirest it's own dedicated mocking layer. It's still young and not as robust or mature as Spring's mock but it might get you by/ Any feedback is welcome

https://github.com/Kong/unirest-java/tree/main/unirest-mocks

shakyasudeep commented 3 years ago

Hi, @shakyasudeep Spring MockRestServiceServer is a great tool, but it only works with Spring RestTemplate. It binds itself to the insides of a RestTemplate instance and intercepts the calls. It's never going to work with Unirest (or Apache Client, or Feign, or etc)

It's a little weird you would post this today because this last weekend we released as part of Unirest it's own dedicated mocking layer. It's still young and not as robust or mature as Spring's mock but it might get you by/ Any feedback is welcome

https://github.com/Kong/unirest-java/tree/main/unirest-mocks

Thanks for the reply @ryber . I was not aware about unirest-mocks. I will try with unirest-mocks.

ryber commented 3 years ago

I'm going to go ahead and close this.

shakyasudeep commented 3 years ago

I'm going to go ahead and close this.

OK.