How to cover equals method in code coverage - java

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.

Related

The java right implemantion of equals?

i try to find out what is the right way to implement java equals.
reading on the net I saw that there are many Thoughts on the subject I narrow down to 2 options
1 using instance of and on using getClass() != obj.getClass()
to follow the rules of :
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
this is my final result :
public class Foo {
private List<Long> days;
private String project;
public boolean equals(Object obj) {
if (this == obj)
return true;
//avoid symmetry problem
if (obj == null || getClass() != obj.getClass())
return false;
Foo test = (Foo)obj;
return equals(this.project,test.project) && equals(this.days,test.days);
}
public static boolean equals(Object a,Object b) {
return a == b || a != null && b!=null && a.equals(b);
}
}
what do you say ?
Your code looks good in general. getClass() != obj.getClass() is sufficient enough. It will only fail for positive scenario if someone goes crazy with tricky custom code to load same class with different classloaders.
I would also replace your custom equals on fields with standard Objects.equals at the end:
return Objects.equals(days, foo.days) &&
Objects.equals(project, foo.project);
It's always good to override hashcode when you override equals too.
You may want to custom the equals on the list if the order matter.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo foo = (Foo) o;
return Objects.equals(days, foo.days) && Objects.equals(project, foo.project);
}
#Override
public int hashCode() {
return Objects.hash(days, project);
}
You would rewrite your code with the following consideration, we use equals() to compare objects otherwise, = sign used to compare data types

How to test Single Linked List using Assert.assertEquals()

i am trying to test singly linked list using Assert.assertEqual(expected, actual) the linked list has a node index and a value. how can i use Assert.assertEquals() to test it.
This is my code
#Test
void nonEmptyTest() throws ListAccessError {
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
SingleLinkedList<Integer> expList = new SingleLinkedList<Integer>();
list.add(0,10);
list.add(1,20);
list.add(2,30);
expList.add(0,10);
expList.add(1,20);
expList.add(2,30);
Assert.assertEquals(expList, list);
}
You need to override boolean equals(Object obj) method for you to expect the assert on the actual values of the list.
Here's a sample on how to override
(Note: I don't know your implementation of SingleLinkedList, you can get an idea from the following code and implement accordingly)
#Override
public boolean equals(Object obj) {
if (obj == null)
return false;
SingleLinkedList<Integer> listToCompare = (SingleLinkedList<Integer>) obj;
SingleLinkedList<Integer> thisList = this;
while (listToCompare != null && thisList != null) {
if (!listToCompare.getData().equals(thisList.getData()))
return false;
listToCompare = listToCompare.getNext();
thisList = thisList.getNext();
}
if (listToCompare == null && thisList == null)
return true;
return false;
}
If you want to compare two different objects to find out whether they're equal, your class that defines those objects generally needs to implement the equals() method. Otherwise Java has no way to know what 'equality' is supposed to mean.
That is, your problem is not in the unit test, it's in the class being tested. The
unit test did its job :-)

Casting Object to a Pair

I am trying to get my "equals" method to work but am having trouble. This is supposed to be easy but I am new to this. I thought I had to cast otherOject to a pair in order to be able to use .fst and check if the pairs are equal, however I am having difficulty "casting" properly. Any help would be much appreciated. I have the following methods:
public void setFst(T1 aFirst)
{
fst = aFirst;
}
public void setSnd(T2 aSecond)
{
snd = aSecond;
}
public boolean equals(Object otherObject)
{
Pair aPair = (Pair)otherOject; //--------> ???
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
{
return true;
}
}
Here are the errors I am getting:
./Pair.java:84: cannot find symbol
symbol : variable fst
location: class java.lang.Object
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
^
./Pair.java:84: cannot find symbol
symbol : variable snd
location: class java.lang.Object
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
^
This isn't that easy, this has more pitfalls than you'd think.
Your equals method has to allow for having objects belonging to classes other than the class you're writing it for. You have to do is check to see if the argument is also a Pair:
if (otherObject == null) return false;
if (otherObject.getClass() != Pair.class) return false;
After this check is passed you can cast safely, and assign the cast object to a new local variable:
Pair otherPair = (Pair)otherObject;
then use the fields on otherPair for your equals check. At this point you're done with the otherObject parameter and the rest of the equals method shouldn't reference it anymore.
the whole thing would look like
public boolean equals(Object otherObject) {
if (otherObject == null) return false;
if (getClass() != otherObject.getClass()) return false;
Pair otherPair = (Pair)otherObject;
return otherPair.fst.equals(this.fst) && otherPair.snd.equals(this.snd);
}
assuming that fst and snd are not allowed to be null. Calling the equals method on a null member will cause a NullPointerException. To avoid the NPE if fst or snd are null, check if the members are null before calling equals on them:
public boolean equals(Object otherObject) {
// check if references are the same
if (this == otherObject) return true;
// check if arg is null or something other than a Pair
if (otherObject == null) return false;
if (getClass != otherObject.getClass()) return false;
Pair otherPair = (Pair)otherObject;
// check if one object's fst is null and the other is nonnull
if (otherPair.fst == null || this.fst == null) {
if (otherPair.fst != null || this.fst != null) return false;
}
// check if one object's snd is null and the other is nonnull
if (otherPair.snd == null || this.snd == null) {
if (otherPair.snd != null || this.snd != null) return false;
}
// each member is either null for both or nonnull for both
return ((otherPair.fst == null && this.fst == null) || otherPair.fst.equals(this.fst))
&& ((otherPair.snd == null && this.snd == null) || otherPair.snd.equals(this.snd));
}
This last bit is annoying to write, IDEs will generate this stuff for you. Here's what Eclipse generates:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (fst == null) {
if (other.fst != null)
return false;
} else if (!fst.equals(other.fst))
return false;
if (snd == null) {
if (other.snd != null)
return false;
} else if (!snd.equals(other.snd))
return false;
return true;
}
Remember to implement hashCode too.
The major problem is that after you have cast, you are comparing with the original otherObject, which still is an instance of the Object class, rather than the variable on the Left hand side of your assignment aPair which has the type Pair
So, this should get you going:
public boolean equals(Object otherObject)
{
Pair aPair = (Pair)otherOject; //--------> ???
if(aPair.fst.equals(this.fst) && aPair.snd.equals(this.snd))
{
return true;
}
}
Be careful here though. What you are doing is called unchecked casting. Your compiler might warn you about it. You don't know whether the object being passed to your equals method really can be cast to a Pair - it has to be an instance of Pair or a subclass of Pair for that to be a valid action. So, your cast might fail at runtime if, for instance, you pass a String or Integer object into the method.
EIT
#NathanHughes's more complete answer to this question shows you how to check the casting (using instanceof keyword), so I won't repeat it here.
I recommend the Oracle java tutorial docs for this kind of thing. Check this tutorial for classes and subclasses - the very end is about how to cast and check if it is valid to cast.
Best to do
#Override
public boolean equals(Object otherObject) {
if (otherObject instanceof Pair) {
Pair otherPair = (Pair)otherObject;
return otherPair.fst.equals(fst) && otherPair.snd.equals(snd))
}
return false;
}
Your otherObject is an instance of Object and there is no fst on the Object. Need to change to aPair.fst.equals.

Using assert statement to test method

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

Point of exit from a method in Java

In Eclipse, is there any way to find which return statement a method returned from without logging flags at every return statment?
For example:
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ABC)) {
return false;
}
ABC other = (ABC) obj;
if (var1 == null) {
if (other.var1 != null) {
return false;
}
} else if (!var1.equals(other.var1)) {
return false;
}
return true;
}
In this case, how do I find out at which point my equals method returned?
No, but a more understandable and debug friendly code can be with a boolean local variable that represents the result.
then you can see with debugger who assign it when and the return value before returned.
No. This is one reason that some people prefer single point of exit:
Why should a function have only one exit-point?
Note also the links in the first comment on that question.
Use breakpoints in debug mode.

Categories