Wojtek
Wojtek

Reputation: 2524

Rest Assured - deserialize Response JSON as List<POJO>

I have a POJO Artwork. I'm retrieving a List of those objects from a RESTful webservice in the HTTP response body in JSON format. I'm trying to write a Rest Assured-based test that would analyze the returned list. The code looks like this:

Response response = get("/artwork");
List returnedArtworks = response.getBody().as(List.class)

The problem is, I can't get Rest Assured to parse the returned JSON as List<Artwork>. Instead, I get a List<LinkedHashMap>. The map has a proper structure, i.e. could be mapped by Jackson to Artwork object, but I'd like to avoid mapping it manually.

JSON mappings in my model are OK, because when I map single object like this:

Artwork returnedArtwork = response.getBody().as(Artwork.class);

it works fine.

Is it possible to get returnedArtworks as List<Artwork>?

Upvotes: 38

Views: 67643

Answers (6)

Currently we have a better solution using Typeref which will help to extract generic objects

List<Artwork> returnedArtworks = response.getBody().as(new TypeRef<List<Artwork>>() {});

or

response.as(new TypeRef<List<Artwork>>() {});

Upvotes: 0

Jmini
Jmini

Reputation: 9497

Rest-assured provide an as(java.lang.reflect.Type) next to the version expecting a Class used in the question.

java.lang.reflect.Type type; //TODO defines the type.
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)

In my opinion the way the type variable depends from the serialization lib that is used.


If using Gson, as pointed out by Purushotham's answer, TypeToken can be used. I prefer using it directly in rest-assured:

Type type = new TypeToken<List<Artwork>>(){}.getType();
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)

When using Jackson, the solution is to use the TypeFactory (javadoc, source) to tell to which type it should be de-serialized:

Type type = TypeFactory.defaultInstance().constructCollectionLikeType(ArrayList.class, Artwork.class);
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)

Upvotes: 3

Vytautas
Vytautas

Reputation: 75

With REST assured 3.0.2 you can simply check if content exists in the array

when().get("/artwork").then().body("artworks", hasItem("some art");
//or check multiple values in array
when().get("/artwork").then().body("artworks", hasItems("some art", "other art");

This way you will avoid complexity in your code by converting JSON to list more examples how to check response content can be found link

Upvotes: 0

Seren
Seren

Reputation: 151

this solution works for version 3.0.2 (io.restassured):

  JsonPath jsonPath = RestAssured.given()
     .when()
     .get("/order")
     .then()
     .assertThat()
     .statusCode(Response.Status.OK.getStatusCode())
     .assertThat()
     .extract().body().jsonPath();

  List<Order> orders = jsonPath.getList("", Order.class);

This will extract the objects for a structure like this:

public class Order {

private String id;

public String getId(){
return id; }

public void setId(String id){
this.id = id;
}


}

with the given json:

[ 
{ "id" : "5" }, 
{ "id" : "6" }
]

Upvotes: 15

volatilevar
volatilevar

Reputation: 1676

You can do this:

List<Artwork> returnedArtworks = Arrays.asList(response.getBody().as(Artwork[].class));

The trick is to deserialize JSON to an array of objects (because there is no difference between the JSON string of an array or a list), then convert the array to a list.

Upvotes: 46

Purushotham
Purushotham

Reputation: 3818

By using Google's Gson library you can easily parse it to List<Artwork>. Try below code

Gson gson = new Gson();
List<Artwork> returnedArtworks = gson.fromJson(jsonStr, new TypeToken<List<Artwork>>(){}.getType());

//* where jsonStr is the response string(Json) receiving from your Restful webservice

Upvotes: 5

Related Questions