Say I have a class with no equals() method, to which do not have the source. I want to assert equality on two instances of that class.
I can do multiple asserts:
The library Hamcrest 1.3 Utility Matchers has a special matcher that uses reflection instead of equals.
assertThat(obj1, reflectEquals(obj2));
You can use Apache commons lang ReflectionToStringBuilder
You can either specify the attributes you want to test one by one, or better, exclude those you don't want:
String s = new ReflectionToStringBuilder(o, ToStringStyle.SHORT_PREFIX_STYLE)
.setExcludeFieldNames(new String[] { "foo", "bar" }).toString()
You then compare the two strings as normal. For the point about reflection being slow, I assume this is only for testing, so shouldn't be so important.
You can use reflection to "automate" the full equality testing. you can implement the equality "tracking" code you wrote for a single field, then use reflection to run that test on all fields in the object.
I had the exact same conundrum when unit testing an Android app, and the easiest solution I came up with was simply to use Gson to convert my actual and expected value objects into json
and compare them as strings.
String actual = new Gson().toJson( myObj.getValues() );
String expected = new Gson().toJson( new MyValues(true,1) );
assertEquals(expected, actual);
The advantages of this over manually comparing field-by-field is that you compare all your fields, so even if you later on add a new field to your class it will get automatically tested, as compared to if you were using a bunch of assertEquals()
on all the fields, which would then need to be updated if you add more fields to your class.
jUnit also displays the strings for you so you can directly see where they differ. Not sure how reliable the field ordering by Gson
is though, that could be a potential problem.
You can override the equals method of the class like:
@Override
public int hashCode() {
int hash = 0;
hash += (app != null ? app.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
HubRule other = (HubRule) object;
if (this.app.equals(other.app)) {
boolean operatorHubList = false;
if (other.operator != null ? this.operator != null ? this.operator
.equals(other.operator) : false : true) {
operatorHubList = true;
}
if (operatorHubList) {
return true;
} else {
return false;
}
} else {
return false;
}
}
Well, if you want to compare two object from a class you must implement in some way the equals and the hash code method
I know it's a bit old, but I hope it helps.
I run into the same problem that you, so, after investigation, I found few similar questions than this one, and, after finding the solution, I'm answering the same in those, since I thought it could to help others.
The most voted answer (not the one picked by the author) of this similar question, is the most suitable solution for you.
Basically, it consist on using the library called Unitils.
This is the use:
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
Which will pass even if the class User
doesn't implement equals()
. You can see more examples and a really cool assert called assertLenientEquals
in their tutorial.