Rest Assured java.util.HashMap cannot be cast to class java.util.List

Tags: , , , ,



I am working on Rest assured framework to automate API testing. actually I want to get the response as list not as an object. cause I want to do assertions for each element. to check data integrity for each element. I am executing this code:

    List<Category> categories = given().
            headers(
                    "Authorization",
                    "Bearer key",
                    "Content-Type",
                    ContentType.JSON,
                    "Accept",
                    ContentType.JSON)
            .when()
            .get("/rest/V1/categories").then().extract().response().jsonPath().getList("", Category.class);

This is the Category Class:

public class Category  {

private Long id = null;

private Long parent_id = null;

private String name = null;

private boolean is_active = true;

private int position = 0;

private int level = 0;

private int product_count = 0;

private ArrayList<Category> children_data = null;

public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}

public Long getParent_id() {
    return parent_id;
}
public void setParent_id(Long parent_id) {
    this.parent_id = parent_id;
}

/**
 **/
public Boolean getIs_active() {
    return is_active;
}
public void setIs_active(Boolean is_active) {
    this.is_active = is_active;
}

/**
 **/
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

/**
 **/
public int getProduct_count() {
    return product_count;
}
public void setProduct_count(int product_count) {
    this.product_count = product_count;
}

public int getLevel() {
    return level;
}
public void setLevel(int level) {
    this.level = level;
}

public int getPosition() {
    return position;
}
public void setPosition(int position) {
    this.position = position;
}

/**
 **/
public List<Category> getChildren_data() {
    return children_data;
}
public void setChildren_data(List<Category> children_data) {
    this.children_data = children_data;
}

This is the console log:

java.lang.ClassCastException: class java.util.HashMap cannot be cast to class java.util.List (java.util.HashMap and java.util.List are in module java.base of loader 'bootstrap')

My Json raw:

{ “id”: 2, “parent_id”: 1, “name”: “Default Category”, “is_active”: true, “position”: 1, “level”: 1, “product_count”: 2046, “children_data”: [ { “id”: 38, “parent_id”: 2, “name”: “What’s New”, “is_active”: true, “position”: 1, “level”: 2, “product_count”: 0, “children_data”: [] }, { “id”: 20, “parent_id”: 2, “name”: “Women”, “is_active”: true, “position”: 2, “level”: 2, “product_count”: 1012, “children_data”: [ { “id”: 21, “parent_id”: 20, “name”: “Tops”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 784, “children_data”: [ { “id”: 23, “parent_id”: 21, “name”: “Jackets”, “is_active”: true, “position”: 1, “level”: 4, “product_count”: 186, “children_data”: [] }, { “id”: 24, “parent_id”: 21, “name”: “Hoodies & Sweatshirts”, “is_active”: true, “position”: 2, “level”: 4, “product_count”: 182, “children_data”: [] }, { “id”: 25, “parent_id”: 21, “name”: “Tees”, “is_active”: true, “position”: 3, “level”: 4, “product_count”: 192, “children_data”: [] }, { “id”: 26, “parent_id”: 21, “name”: “Bras & Tanks”, “is_active”: true, “position”: 4, “level”: 4, “product_count”: 224, “children_data”: [] } ] }, { “id”: 22, “parent_id”: 20, “name”: “Bottoms”, “is_active”: true, “position”: 2, “level”: 3, “product_count”: 228, “children_data”: [ { “id”: 27, “parent_id”: 22, “name”: “Pants”, “is_active”: true, “position”: 1, “level”: 4, “product_count”: 91, “children_data”: [] }, { “id”: 28, “parent_id”: 22, “name”: “Shorts”, “is_active”: true, “position”: 2, “level”: 4, “product_count”: 137, “children_data”: [] } ] } ] }, { “id”: 11, “parent_id”: 2, “name”: “Men”, “is_active”: true, “position”: 3, “level”: 2, “product_count”: 982, “children_data”: [ { “id”: 12, “parent_id”: 11, “name”: “Tops”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 678, “children_data”: [ { “id”: 14, “parent_id”: 12, “name”: “Jackets”, “is_active”: true, “position”: 1, “level”: 4, “product_count”: 176, “children_data”: [] }, { “id”: 15, “parent_id”: 12, “name”: “Hoodies & Sweatshirts”, “is_active”: true, “position”: 2, “level”: 4, “product_count”: 208, “children_data”: [] }, { “id”: 16, “parent_id”: 12, “name”: “Tees”, “is_active”: true, “position”: 3, “level”: 4, “product_count”: 192, “children_data”: [] }, { “id”: 17, “parent_id”: 12, “name”: “Tanks”, “is_active”: true, “position”: 4, “level”: 4, “product_count”: 102, “children_data”: [] } ] }, { “id”: 13, “parent_id”: 11, “name”: “Bottoms”, “is_active”: true, “position”: 2, “level”: 3, “product_count”: 304, “children_data”: [ { “id”: 18, “parent_id”: 13, “name”: “Pants”, “is_active”: true, “position”: 1, “level”: 4, “product_count”: 156, “children_data”: [] }, { “id”: 19, “parent_id”: 13, “name”: “Shorts”, “is_active”: true, “position”: 2, “level”: 4, “product_count”: 148, “children_data”: [] } ] } ] }, { “id”: 3, “parent_id”: 2, “name”: “Gear”, “is_active”: true, “position”: 4, “level”: 2, “product_count”: 46, “children_data”: [ { “id”: 4, “parent_id”: 3, “name”: “Bags”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 14, “children_data”: [] }, { “id”: 5, “parent_id”: 3, “name”: “Fitness Equipment”, “is_active”: true, “position”: 2, “level”: 3, “product_count”: 23, “children_data”: [] }, { “id”: 6, “parent_id”: 3, “name”: “Watches”, “is_active”: true, “position”: 3, “level”: 3, “product_count”: 9, “children_data”: [] } ] }, { “id”: 9, “parent_id”: 2, “name”: “Training”, “is_active”: true, “position”: 5, “level”: 2, “product_count”: 6, “children_data”: [ { “id”: 10, “parent_id”: 9, “name”: “Video Download”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 6, “children_data”: [] } ] }, { “id”: 7, “parent_id”: 2, “name”: “Collections”, “is_active”: false, “position”: 5, “level”: 2, “product_count”: 989, “children_data”: [ { “id”: 8, “parent_id”: 7, “name”: “New Luma Yoga Collection”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 347, “children_data”: [] }, { “id”: 34, “parent_id”: 7, “name”: “Erin Recommends”, “is_active”: true, “position”: 2, “level”: 3, “product_count”: 279, “children_data”: [] }, { “id”: 35, “parent_id”: 7, “name”: “Performance Fabrics”, “is_active”: true, “position”: 3, “level”: 3, “product_count”: 310, “children_data”: [] }, { “id”: 36, “parent_id”: 7, “name”: “Eco Friendly”, “is_active”: true, “position”: 4, “level”: 3, “product_count”: 247, “children_data”: [] }, { “id”: 39, “parent_id”: 7, “name”: “Performance Sportswear New”, “is_active”: true, “position”: 5, “level”: 3, “product_count”: 0, “children_data”: [] }, { “id”: 40, “parent_id”: 7, “name”: “Eco Collection New”, “is_active”: true, “position”: 6, “level”: 3, “product_count”: 0, “children_data”: [] } ] }, { “id”: 29, “parent_id”: 2, “name”: “Promotions”, “is_active”: false, “position”: 6, “level”: 2, “product_count”: 654, “children_data”: [ { “id”: 30, “parent_id”: 29, “name”: “Women Sale”, “is_active”: true, “position”: 1, “level”: 3, “product_count”: 224, “children_data”: [] }, { “id”: 31, “parent_id”: 29, “name”: “Men Sale”, “is_active”: true, “position”: 2, “level”: 3, “product_count”: 39, “children_data”: [] }, { “id”: 32, “parent_id”: 29, “name”: “Pants”, “is_active”: true, “position”: 3, “level”: 3, “product_count”: 247, “children_data”: [] }, { “id”: 33, “parent_id”: 29, “name”: “Tees”, “is_active”: true, “position”: 4, “level”: 3, “product_count”: 192, “children_data”: [] } ] }, { “id”: 37, “parent_id”: 2, “name”: “Sale”, “is_active”: true, “position”: 6, “level”: 2, “product_count”: 0, “children_data”: [] } ] }

Answer

You want to get a List<> using getList() method but your JSON doesn’t start with List. Instead of getList use getObject and it will work. getObject() maps the JSON to POJO class of your choice.

While deserializing JSON, you might encounter below issue

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of dataentities.Category (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

All you need to do is add a dependency to tell Rest-Assured which deserializer you want to use. My personal choice is:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
</dependency>

EDIT: To deserialize JSON into a POJO you use getObject() method like this:

Category category = jsonPath.getObject("", Category.class);

EDIT: You should make your Category class fields public OR create setters and getters. Otherwise, there will be exceptions.



Source: stackoverflow