1

I am using RestAssured framework for api calls and I want to create a method that will return give me value from the JSON response in the specific variable type.
I want to use generic return type but I don't like me implementation.
The RestAssured getList() returns a list of values according to JSON path and cast to value type. When I implement the getList() method, I have to cast the result to T in order to comply to the return value type:

public <T> T getValuesFromResponse(Response response, ValueTypeEnum value) {
    T t = null;
    switch (value) {
        case ID:
            //Will return List<Integer>
            t = (T) response.thenReturn().jsonPath().getList("data.id", Integer.class);
            break;
        case NAME:
            //Will return List<String>
            t = (T) response.thenReturn().jsonPath().getList("data.name", String.class);
            break;
    }
    return t;
}

When I want to call this method, I have to cast the values again to the type I need, i.e:

((List<Integer>) getValuesFromResponse(response, ValueTypeEnum.ID)).get(0)

How do I avoid the double casting?
Is my implementation correct for using generic List<T> return type?

assylias
  • 321,522
  • 82
  • 660
  • 783
Leon Proskurov
  • 135
  • 1
  • 14
  • I tried that, but it does not compile. ```public List getValuesFromResponse(Response response, DeviceValues value) { return response.thenReturn().jsonPath().getList("data.id", Integer.class); } ``` the error is: Incompatible equality constraint: T and Integer – Leon Proskurov May 18 '20 at 11:50

1 Answers1

0

What do you think about using a method like this:

 public <T> List<T> getValuesFromResponse(Response response, String key, Class <T> clazz) {
    return response.thenReturn().jsonPath().getList(key, clazz);
}

... and then call it as:

List<Integer> listOfIds = getValuesFromResponse (response, "data.id", Integer.class);
List<String> listOfNames = getValuesFromResponse (response, "data.name", String.class);

I have't tried it to compile with the real 'Response' class, but I think this should work. Please let me know.

Slavomir
  • 351
  • 2
  • 8
  • This works, but it requires the "user" to define the return class type, while i wanted it to be more generic. strange that if i use "clazz" that is defined as Integer.class it compiles, but if i use straight Integer.class, it wont – Leon Proskurov May 18 '20 at 12:13
  • If I understand correctly, you want to have a method that returns a list of objects of particular class to avoid typecast. And want only to pass ValueTypeEnum. This enumeration value represents: (1) what is the name of the field in the response like:'data.name' and (2) what is the type (class of the objects) that the list will contain, like: 'String'. Identifying values of the ValueTypeEnum means it is a runtime processing, while avoiding type cast means we know compile time what class is returned in particular scenario. I am not sure those two are possible at the same time. Good luck. – Slavomir May 18 '20 at 15:50