Using assert statement to test method - java

So i have an equals method for both subclasses CheckingAccount and SavingAccount and i also have a superclass named BankAccount. I am confusing at how to test the equals method using assert statement? Thanks very much.
Here is the code for equals method
In CheckingAcc
public boolean equals(Object object) {
if (this == object)
return true;
if (object == null)
return false;
if (getClass() != object.getClass())
return false;
CheckingAcc other = (CheckingAcc) object;
if (accountNumber != other.accountNumber)
return false;
return true;
}
In SavingAcc
public boolean equals(Object object) {
if (this == object)
return true;
if (object == null)
return false;
if (getClass() != object.getClass())
return false;
SavingAcc other = (SavingAcc) object;
if (accountNumber != other.accountNumber)
return false;
return true;
}

Typically, you'd write a unit test program that creates some objects, sets them up, and use asserts to verify conditions that you are expecting to be true. The program will alert you when an assertion fails.
So in your test program you could, for example:
CheckingAccount test = new CheckingAccount(1);
CheckingAccount other = new CheckingAccount(2);
SavingAccount anotherTest = new SavingAccount();
SavingAccount anotherOther = new SavingAccount();
anotherTest.accountNumber = 3;
anotherOther.accountNumber = 3;
assert !test.equals(other); // this should evaluate to true, passing the assertion
assert anotherTest.equals(anotherOther); // this should evaluate to true, passing the assertion
It looks like you use an account number as a means of equality for your accounts, so I'm assuming when creating these objects, you either pass the account number as a parameter for the constructor, or assign it explicitly
Obviously this is a very meager example, but I'm not sure about the creation/structure of your objects. But this could be extended to provide more meaningful testing, as long as you get the gist.
EDIT so to fully test your equals method, you can set up your assertions so that they all should evaluate to true (and pass) as well as testing all the functionality of your equals method (complete code coverage)
CheckingAccount newTest = new CheckingAccount(1);
CheckingAccount secondTest = new CheckingAccount(1);
SavingAccount newOther = new SavingAccount(3);
assert newTest.equals(newTest); // test first if
assert !newTest.equals(null); // test second if
assert !newTest.equals(newOther) // test third if
assert newTest.equals(secondTest); // test fourth if

Related

Not able to return false in equals() method when object o is null. I have added my equals() implementation as well the test case

My equals() method:
Here when in second if statement when my my object is null for example, I should return false but for some reason my code fails to do so. Any help?
public boolean equals(Prof o) {
boolean res = false;
if(this == o) {
res = true;
}
if(o == null || this.getClass() != o.getClass()) {
res = false;
}
Prof other = (Prof) o;
if(this.year == other.year) {
if(this.id.equals(other.id)) {
res = true;
}
}
else {
res = false;
}
return res;
}
Test Case:
public void test02_ProfEqualHash() {
Prof p1 = new Prof("John S Lee", "yu213", 5);
assertTrue(p1.equals(p1));
Prof p0 = null; // null
assertFalse(p1.equals(p0)); // my equals() implementation fails here
Date d = new Date();
String s = "Hello";
assertFalse(p1.equals(d));
assertFalse(p1.equals(s));
Prof p2 = new Prof("John L", "yu213", 5);
assertTrue(p1.equals(p2));
assertTrue(p1.hashCode() == p2.hashCode());
assertTrue(p2.equals(p1));
Prof p3 = new Prof("John S Lee", "yu203", 5);
assertFalse(p1.equals(p3));
//assertNotEquals(p1.hashCode(), p3.hashCode());
Prof p4 = new Prof("Tracy T", "yu053", 2);
assertFalse(p1.equals(p4));
//assertNotEquals(p1.hashCode(), p4.hashCode());
Prof p5 = new Prof("John S Lee", "yu213", 8);
assertFalse(p1.equals(p5));
//assertTrue(p1.hashCode() != p5.hashCode());
}
First of all, in order to correctly override Object's equals(), the method signature should be:
public boolean equals(Object o) {
....
}
Even though your test code calls your equals() method, JDK classes that expect Object's equals() signature will not.
In addition, you should return false immediately when you find that the o argument is null, in order not to access it later in your method (which would cause NullPointerException).
A correct implementation can look like this:
public boolean equals (Object o)
{
if (this == o) {
return true;
}
if (o == null || !(o instanceof Prof)) {
return false;
}
Prof other = (Prof) o;
return this.year == other.year && this.id.equals(other.id);
}
In Java Object class is the superclass of every class. So in order to override the equal method defined in the Object class, you need to follow the same method definition, which is:
#Override
public boolean equals(Object other) {
// here goes your implementation class
}
Since your definition of equals has Prof as an argument, hence you are not actually overriding the Object equals method.
For more information on the equals contract, you can read Item10 from Effective Java book by Josh Bloch.
Also, if your class has an equals method, then you should always define the hashCode implementation as well. Here is the implementation of this method:
#Override
public int hashCode() {
return Objects.hash(year, id);
}

How to cover equals method in code coverage

New to code coverage, would like to have some insights...
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.email == null) ? (other.email != null) : !this.email.equals(other.email)) {
return false;
}
if (this.age != other.age && (this.age == null || !this.age.equals(other.age))) {
return false;
}
return true;
}
How do I cover this in jcoco code coverage.
To have this class 100% tested you should create a test for every if and ?: operator. Every part of the code should be tested. For instance, the first if (this == obj), you should have a test where you do
#Test
public void testEqualsSameObj() {
MyClass sut = new MyClass(); // sut == system under test
assertTrue (sut.equals(sut));
}
And now make the next test for passing null:
#Test
public void testEqualsNull() {
MyClass sut = new MyClass(); // sut == system under test
assertFalse (sut.equals(null));
}
And continue with the next condition, until you cover all branches in the code.
You can take the sut from the method and store it in the test class as a member variable.
The equals could have 0% coverage because you might have not included the lombok.config file with with generated annotations as true.
Set,
config.stopBubbling = true;
lombok.addLombokGeneratedAnnotation = true
in lombok.config file
I'm not sure about the what method you are trying to get covered. What I understood from your question is: you are trying to cover equals code of the person.
So in order to cover that
1) have your name property of current object which referred by this as null
2) have your name property of current object as not null to cover the equals part of the code.
To understand more on this learn how ternary (? :) operator works.
I hope this answer helps.

issue with overriding .equals() method

I was working on overriding .equals() in java for an "Item" class with a Constructor in the form of:
public Item(final String theName, final BigDecimal thePrice, final int theBulkQuantity,
final BigDecimal theBulkPrice) {
myName = Objects.requireNonNull(theName);
myPrice = Objects.requireNonNull(thePrice);
myBulkQuantity = theBulkQuantity;
myBulkPrice = theBulkPrice;
}
using this .equals method:
#Override
public boolean equals(final Object theOther) {
boolean result = false;
if (this == theOther) {
result = true;
}
else if (theOther != null && theOther == this.getClass()) {
final Item other = (Item) theOther;
if ((this.myName.equals(other.myName))
&& (this.myBulkQuantity == other.myBulkQuantity)
&& (this.myPrice.equals(other.myPrice))
&& (this.myBulkPrice.equals(other.myBulkPrice))) {
result = true;
}
}
return result;
}
I'm a new Computer Science student and this is my first attempt at overriding. I would have overlooked this if I had not used JUnit testing using the following:
testItemB = new Item("ItemB", new BigDecimal("5.00"), 5, new BigDecimal("20.00"));
testItemC = new Item("ItemB", new BigDecimal("5.00"), 5, new BigDecimal("20.00"));
and got an assertion error saying that they weren't equivalent. At first glance I am pretty sure that I got everything but do you guys happen to see anything glaring?
In the equals() method you compared the object instance theOther with this.getClass() which will always return false since your are comparing an instance with a class type.
Depending on your use case, you may use
obj1.getClass().equals(obj2.getClass())
or
theOther instanceof Item

hashset return false when should return true

I'm programming a Maze and I have some problems.
I have:
HashSet<State> closedList = HashSet<State>(); //it hold State objects
My State class look like this:
public class State implements Comparable<State>{
private double f;
private double g;
private String state;
private State prev;
.
.
.
closedList.add(state);
closedList().contains(state); // this equals true
but when I do this:
State temp = State(0,0,"");
temp.setStateName(state.getStateName());
closedList().contains(temp); // this equals false
I have implemented equals and hashCode in State:
#Override
public int hashCode(){
return state.hashCode();
}
#Override
public boolean equals(Object object){
if(this.state == object){
return true;
}
if(object == null || object.getClass() != this.getClass()){
return false;
}
return false;
}
closedList().contains(state); // this equals true
This is a red herring, it only returns true because HashSet checks with == before it makes a call to equals.
What you should try is something like this:
State temp = new State(0, 0, "");
System.out.println(temp.equals(temp));
And you will find this returns false. Why is that? Well let's follow the logic through.
First, you have this check:
if(this.state == object){
return true;
}
If you really intended this to be the way it is, it means you were expecting equals to be called with the String state as the argument, like this:
temp.equals(temp.getStateName())
(And it's the case the above call would return true.) This is incorrect, one would not expect equals to return true for unrelated classes (and in terms of the equals contract, it's the case this is not symmetric). I assume this is unintended and just like a mistake. You should think more carefully about what your code is doing when you are writing it.
Also you should be comparing Strings with equals, not ==.
Then there is this construct:
if(object == null || object.getClass() != this.getClass()){
return false;
}
return false;
This is pointless because first what it implies logically is this, returning false either way:
if(object == null || object.getClass() != this.getClass()){
return false;
} else {
return false;
}
And, second, combined with the earlier check it is not particularly logical:
if(this.state == object)
return true;
if(object.getClass() != this.getClass())
return false;
This is returning true if object is == to a String but returning false if object's class is not State. These are mutually exclusive.
So the equals implementation you wrote doesn't work. The correct equals to match your hashCode is like this:
#Override
public boolean equals(Object object){
if(object == null || object.getClass() != this.getClass()){
return false;
}
State other = (State)object;
return this.state.equals(other.state);
}
First check that the object is not null and that its class is State (you had that part right), then check that the state member is equal to the other object's state member.

How to compare the data of two same Objects in Java

I have a class
MyData
and its object
myData
In that Class MyData .. there are multiple fields
like
int id
String name
String desc
etc ..
Now i have two objects of this class ..
Is it possible to check that if the data of these two object are all the same , Like both objects have the same Id ,same Name ,same Desc ... Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) As there are dozens of fields of this object .
I am using JAVA with GWT
Some implementation i came across.. Not sure if this is some thing possible .valid
private static String oldSequence = "";
boolean changed(TestSequence sequence) {
String newSequence = serializeToString(sequence);
boolean changed = !newSequence.equals(oldSequence);
oldSequence = newSequence;
return changed;
}
private static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(obj);
return b.toByteArray();
}
private static String serializeToString(Object obj) {
try {
return new String(serialize(obj));
} catch (Exception ex) {
return "" + ex;
}
}
Thanks
You should override hashCode() and equals() method. you can generate these from IDE.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MyData)) return false;
MyData myData = (MyData) o;
if (id != myData.id) return false;
if (!desc.equals(myData.desc)) return false;
if (!name.equals(myData.name)) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + name.hashCode();
result = 31 * result + desc.hashCode();
return result;
}
Now you can compare the objects. That's it.
Conventional way is to override equals and hashCode methods. Java standard libraries, for instance Map s, List s, Set s use the equals and hashCode functions for equality testing. The code below also null-safe;
Here is the code for your case;
public class MyData {
int id;
String name;
String desc;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyData myData = (MyData) o;
if (id != myData.id) return false;
if (desc != null ? !desc.equals(myData.desc) : myData.desc != null) return false;
if (name != null ? !name.equals(myData.name) : myData.name != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (desc != null ? desc.hashCode() : 0);
return result;
}
}
and you can test the equality by;
....
Mydata d1 = new...
Mydata d2 = new...
boolean areTheyEqual = d1.equals(d2);
However if you are not allowed to make a compare field by field then you can use byte arrays, there is no need to convert them to strings.
.....
public boolean equals(Object other){
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
byte[] bytesThis = serialize(this);
byte[] bytesOther = serialize(other);
if(bytesOther.length != bytesThis.length) return false;
return Arrays.equals(bytesThis, bytesOther);
}
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(obj);
return b.toByteArray();
}
...
GWT doesn't make a difference to your requirement.
There is no direct way.
You have to define your equality to check weather they are equal or not. That is overriding equals() method.
#Override
public boolean equals(Object obj) { ...
Before doing:Right way to implement equals contract
Like everyone else is saying, you should override the equals() and hashCode() methods.
Note that you don't have to do this manually. In Eclipse you can simply click on Source/generate hashCode() and equals() and it will do the work for you. I am sure other IDEs have similar feature as well.
If you don't want to add any more code when you add a new field, you can try iterating over fields.
You said "Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) ", I couldn't figure out whether you don't want to check for each field for equality, or don't want to WRITE a check for each field for equality. I assumed the latter since you tried to add an equality comparison method by using bytewise checks.
Anyways, the code to check each field follows. You can copy/paste to any object. If, in the future, you want some fields to be checked and some not, you can use annotations.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyData myData = (MyData) o;
Field[] fields = this.getClass().getDeclaredFields();
for(Field field:fields){
Object o1 = null;
Object o2 = null;
try {
o1 = field.get(this);
o2 = field.get(o);
} catch (IllegalAccessException e) {
return false;
}
if(o1 == null && o2 != null) return false;
if(o2 == null && o1 != null) return false;
if(o2 == null && o1 == null) continue;
if(!o2.equals(o1)) return false;
}
return true;
}
No.
You have to override the equals() method and compare the objects in that.
Override the equals method of the object in MyData and check the fields independently.
Serialize your objects and compare the results!
You just should be wise in selection of your serialization method.
Override hashCode() and equals() methods
hashCode()
This method provides the has code of an object.
Basically the default implementation of hashCode() provided by Object is derived by mapping the memory address to an integer value. If look into the source of Object class , you will find the following code for the hashCode.
public native int hashCode();
It indicates that hashCode is the native implementation which provides the memory address to a certain extent. However it is possible to override the hashCode method in your implementation class.
equals()
This method is used to make equal comparison between two objects. There are two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I hope that you know the difference between this two. More specifically the .equals() refers to equivalence relations. So in broad sense you say that two objects are equivalent they satisfy the equals() condition.

Categories