HashCodeMethodTester class provides
testHashCodeMethod method, which verifies that the hashCode method complies
with the HashCode Contract.
What
is the contract of HashCode?
As per Javadoc, hashCode method should
satisfy following points.
a. Whenever it is invoked on the same
object more than once during an execution of a Java application, the hashCode
method must consistently return the same integer, provided no information used
in equals comparisons on the object is modified. This integer need not remain
consistent from one execution of an application to another execution of the
same application.
b. If two objects are equal according to
the equals(Object) method, then calling the hashCode method on each of the two
objects must produce the same integer result.
c. It is not required that if two objects
are unequal according to the equals(java.lang.Object) method, then calling the
hashCode method on each of the two objects must produce distinct integer
results. However, the programmer should be aware that producing distinct
integer results for unequal objects may improve the performance of hash tables.
I already explained the relation between
hashCode and equals method in following post.
Meanbean implements following algorithms
to test whether hashCode methos is comply with the HashCode Contract (or) not.
Algorithm
|
Description
|
HashCodes Equal test algorithm
|
create instance of class under test,
object x
create instance of class under test,
object y
assert x.equals(x)
assert x.hashCode() == y.hashCode()
|
HashCode Consistent Test Algorithm
|
create instance of class under test,
object x
for i in 1..100 do
assert
hashCode is consistent
end for
|
public class Employee { private String firstName; private String lastName; private int id; private int age; private float salary; public String getFirstName() { return firstName.toUpperCase(); } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName.toUpperCase(); } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); result = prime * result + Float.floatToIntBits(salary); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Employee other = (Employee) obj; if (age != other.age) return false; if (firstName == null) { if (other.firstName != null) return false; } else if (!firstName.equals(other.firstName)) return false; if (id != other.id) return false; if (lastName == null) { if (other.lastName != null) return false; } else if (!lastName.equals(other.lastName)) return false; if (Float.floatToIntBits(salary) != Float.floatToIntBits(other.salary)) return false; return true; } }
import org.junit.Test; import org.meanbean.test.HashCodeMethodTester; public class TestBean { @Test public void testEmployee() { HashCodeMethodTester tester = new HashCodeMethodTester(); tester.testHashCodeMethod(Employee.class); } }
You can also
call testHashCodeMethod by passing EquivalentFactory instance.
import org.junit.Test; import org.meanbean.lang.EquivalentFactory; import org.meanbean.test.HashCodeMethodTester; public class TestBean { @Test public void testEmployee() { HashCodeMethodTester tester = new HashCodeMethodTester(); tester.testHashCodeMethod(new EmployeeFactory()); } public class EmployeeFactory implements EquivalentFactory<Employee>{ public Employee create() { Employee emp = new Employee(); emp.setAge(26); emp.setFirstName("sudhir"); emp.setId(1234); emp.setLastName("Sami"); emp.setSalary(1234567); return emp; } } }
No comments:
Post a Comment