Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does .equals() result in an Assertion Error when comparing two objects...but only sometimes?

I'm working on unit testing for a project at code school and .equals() is giving me some trouble. In my project, .save() is saving into an SQL database. This code passes the unit test:

@Test
public void save_assignsNameToObject() {
  Restaurant testRestaurant = new Restaurant("PokPok","503-444-4444");
  testRestaurant.save();
  Restaurant savedRestaurant = Restaurant.all.get(0);
  assertEquals(savedRestaurant.getName(), "PokPok");
}

But if I change the final line to the following, it will result in an assertion error:

assertTrue(savedRestaurant.equals(testRestaurant));

I debugged using System.out.println() to verify that both values in testRestaurant do ".equal" the corresponding values in savedRestaurant. The following unit test (for an object of another, very similar class) passes using the .equals() method:

@Test
public void save_assignsIdToObject_true() {
  Cuisine testCuisine = new Cuisine("Mexican");
  testCuisine.save();
  Cuisine savedCuisine = Cuisine.all().get(0);
  assertTrue(savedCuisine.equals(testCuisine));
}

Edit: here is my source code for .equals():

@Override
public boolean equals(Object otherRestaurant) {
  if (!(otherRestaurant instanceof Restaurant)) {
    return false;
  } else {
    Restaurant newRestaurant = (Restaurant) otherRestaurant;
    return this.getId() == new Restaurant.getId() &&
           this.getName().equals(newRestaurant.getName()) &&
           ...
           this.getPhone().equals(newRestaurant.getPhone());
    }
  }

Why can .equals() compare some objects and not others? In my code example, the only difference I'm seeing is that one object takes one parameter, and the other takes two.

Thank you!

like image 303
the holla Avatar asked Aug 27 '15 09:08

the holla


1 Answers

By default, equals() on a java object checks that they are the exact same object (not two objects with the same values). http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29

The String object overrides equals() to give a version which will return true for two different objects with the same value, but your custom Restaurant class does not.

You could define a custom equals() e.g.

public class Restaurant {

  private String name;
  private String tel;

  public Restaurant(String name, String tel) {
    this.name = name;
    this.tel = tel;
  }

  /*getters and setters*/

  override public boolean equals(Object obj) {
    if(obj instanceOf Restaurant) {
      Restaurant that = (Restaurant) obj;
      return (this.name.equals(that.getName()) && this.tel.equals(that.getTel()));
    } else {
      return false;
    }
  }
}
like image 97
mattinbits Avatar answered Sep 27 '22 23:09

mattinbits