Reputation: 2524
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
Reputation: 1
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
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
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
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
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
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