lundi 18 mai 2015

how to assert objects are equal in a test with a better error?

how to assert objects are equal with a better error.

Lets say we have a class Truck:

import java.util.List;

public class Truck {

    private String model;
    private String make;
    private int year;

    public Truck(String model, String make, int year) {
        super();
        this.model = model;
        this.make = make;
        this.year = year;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getMake() {
        return make;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}

Test:

@Test
public void truckTest () {

    Truck pickupTruck1 = new Truck("Big 10", "Chevy", 1976);
    Truck pickupTruck2 = new Truck("Big 10", "Chevy", 1975);

    //assertThat(pickupTruck1, equalTo(pickupTruck2));
    //this error is not help full java.lang.AssertionError:
    //Expected: <com.tests.tests.library.Truck@59c0fef4>
    //but: was <com.tests.tests.library.Truck@da27335>

    assertThat(pickupTruck1, samePropertyValuesAs(pickupTruck2));
}

Bellow error is useful:

java.lang.AssertionError:
Expected: same property values as Truck [make: "Chevy", model: "Big 10", parts: null, year: <1975>]
     but: year was <1976>

Now lets say we update the Truck object to be little bit more complicated:

package com.tests.tests.library;

import java.util.List;

public class Truck {

private String model;
private String make;
private int year;
private List<TruckPartsObject> parts;


public Truck(String model, String make, int year) {
    super();
    this.model = model;
    this.make = make;
    this.year = year;
    }

    public String getModel() {
    return model;
    }

    public void setModel(String model) {
    this.model = model;
    }

    public String getMake() {
    return make;
    }

    public void setMake(String make) {
    this.make = make;
    }

    public int getYear() {
    return year;
    }

    public void setYear(int year) {
    this.year = year;
    }

    public List<TruckPartsObject> getParts() {
    return parts;
    }

    public void setParts(List<TruckPartsObject> parts) {
    this.parts = parts;
    }
}

Add TruckPartsObject:

import java.util.HashMap;

public class TruckPartsObject {

    private String name;
    private String price;
    private HashMap<String, String> partsHashMap;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public HashMap<String, String> getPartsHashMap() {
        return partsHashMap;
    }
    public void setPartsHashMap(HashMap<String, String> partsHashMap) {
        this.partsHashMap = partsHashMap;
    }
}

Update the test:

@Test
public void truckTest () {

    Truck pickupTruck1 = new Truck("Big 10", "Chevy", 1976);
    Truck pickupTruck2 = new Truck("Big 10", "Chevy", 1975);               

    List<TruckPartsObject> parts = new ArrayList<TruckPartsObject>();
    TruckPartsObject truckPartsObject = new TruckPartsObject();
    truckPartsObject.setName("part1");
    parts.add(truckPartsObject);
    pickupTruck1.setParts(parts);

    assertThat(pickupTruck1, samePropertyValuesAs(pickupTruck2));
}

Output:

java.lang.AssertionError:
Expected: same property values as Truck [make: "Chevy", model: "Big 10", parts: null, year: <1975>]
     but: parts was <[com.tests.tests.library.TruckPartsObject@11c03d7b]>

How do I fix the last output to be helpful like the original output. Where it tells me why objects are not equals. Want to make the test run output readable and easy to debug.

I tried implementing equals method in the truck object but when the assert fails then then the message is still not helpful.

Updated the truck object to have equals method:

@Override
    public boolean equals(Object obj) {

        Truck MyTruck = (Truck) obj;
        if(this.year == MyTruck.year)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

Update the test:

assertThat(pickupTruck1, equalTo(pickupTruck2));

Output:

java.lang.AssertionError:
Expected: <com.tests.tests.library.Truck@38862c65>
     but: was <com.tests.tests.library.Truck@70ccb7e0>

Aucun commentaire:

Enregistrer un commentaire