Branch coverage in a java super class which is an abstract class - java

How do I solve a cobertura branch coverage issue which is being reflected in a concrete method of an abstract class.
In the below snippet the equals method of the abstract class Currency contains a part where there is a check for the variables SID and Ab which comes after the condition
if (getClass() != obj.getClass()).
This part never gets covered
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (getClass() != obj.getClass())
return false;
final Currency other = (Currency) obj;
if (this.getAb() == null) {
if (other.Ab() != null)
return false;
} else if (!this.getAb().equals(other.getAb()))
return false;
if (this.getSID() < 1 || (this.getSID() != other.getSID()))
return false;
return true;
}
I tried to cover these variables in the test class using the below method but it still doesn't get covered:
Test class:
Currency currency = new Currency() {
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
};
Currency currency1 = new Currency() {
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
};
currency.setAb("SE3421");
currency1.setAb("SE3421");
assertFalse(currency.equals(currency1));
assertTrue((currency1.getAb()).equals(currency.getAb()));
Any help is appreciated.

I would add a new test method, such as this.
#test
public void test_equals() {
Currency currency = new Currency() { };
assertFalse(currency.equals(new String()));
}
One other comment: you should really implement the hashCode method as well.
In hashCode() it says: 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. If you only override equals() and not hashCode() your class violates this contract

Related

indexOf() using ArrayList in java

I've a class A which is as follows:
A{
String name;
ArrayList<Bike> firstArray;
ArrayList<Cycle> secondArray;
// it's constructors and related methods are down lines.
}
and I have two instances of it named a_Obj and b_obj. I compare only the variable ,name inside object a_Obj with b_Obj using indexOf.
My question is how to call indexOf in this case and in other words how to tell the compiler that I just want to compare name of two objects regardless of ArrayLists declared inside the class A.
you can override equals() in your class
Given below is how indexOf has been implemented by default:
public int indexOf(Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return it.previousIndex();
} else {
while (it.hasNext())
if (o.equals(it.next()))
return it.previousIndex();
}
return -1;
}
By overriding the equals method in A to consider just the equality of name, you can make it happen.
Given below is the definition generated by Eclipse IDE:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
A shorter version for the same can be as follows:
#Override
public boolean equals(Object obj) {
if (obj == null)
return false;
A other = (A) obj;
return Objects.equals(name, other.name);
}

Java equals implementation for two objects of the same class returns false when checking getClass()

I have implemented hashCode() and equals() for an object using the default from NetBeans:
#Override
public int hashCode() {
int hash = 5;
hash = 37 * hash + this.unitSystemID;
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
LOGGER.debug(getClass().toString());
LOGGER.debug(this.getClass().getClassLoader().toString());
LOGGER.debug(obj.getClass().toString());
LOGGER.debug(obj.getClass().getClassLoader().toString());
if (getClass() != obj.getClass()) {
return false;
}
final UnitSystem other = (UnitSystem) obj;
if (this.unitSystemID != other.unitSystemID) {
return false;
}
return true;
}
At the logging check-points, I get:
units.UnitSystem - class
com.utilities.domain.units.UnitSystem
units.UnitSystem -
org.springframework.boot.devtools.restart.classloader.RestartClassLoader#42d353e2
units.UnitSystem - class
com.utilities.domain.units.UnitSystem_$$_jvst6b1_19ed
units.UnitSystem -
org.springframework.boot.devtools.restart.classloader.RestartClassLoader#42d353e2
The equality fails at that point and equals returns false.
What is the extra _$$_jvst6b1_19ed? Where does it come from?
From what I understand, the classes should be equal if they are from the same class loader, which these are. I have not had a problem with this implementation anywhere else I have used it. Why is getClass() returning different things?
Unless you actually subclass UnitSystem yourself, exact class matching isn't necessary, so replace
if (getClass() != obj.getClass()) {
return false;
}
with
if (! (obj instanceof UnitSystem)) {
return false;
}
You can't make UnitSystem class final since you want Hibernate to be able to create a subclass proxy, so you don't have absolute guarantee that UnitSystem won't be subclassed by non-Hibernate code, but is such an absolute guarantee really needed?
As #Andreas said in a comment it usually happens when the object has been fetched by a lazy loading. To get the initial object you should to unproxy it first. Here is an example of the unwrapper for a Hibernate
#SuppressWarnings("unchecked")
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new InternalServerException("Entity passed for initialization is null");
}
T unproxy = entity;
Hibernate.initialize(entity);
if (isProxy(entity)) {
unproxy = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return unproxy;
}
public static <T> boolean isProxy(T entity) {
return entity instanceof HibernateProxy;
}

Equals method when dealing with inheritance and no instance variables

This is the way we implement equals method in classes.
Class A (Store) with area as instance variable:
#Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (otherObject == null || getClass() != otherObject.getClass()) {
return false;
}
Store otherStore = (Store) otherObject;
return area == otherStore.area;
}
Class B (StoreToys) extends Class A (Store) and has no instance variables (dealing with inheritance)
How should i write equals method for this class?
If you don't introduce any new fields in StoreToys you can write the check with instanceof to verify that otherObject can be cast to Store.
#Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (!(otherObject instanceof Store)) {
return false;
}
Store otherStore = (Store) otherObject;
return area == otherStore.area;
}

Why these two Java objects do not equals?

I was make some code and found that objects ar eno equals - it is trivial question but not understand how default equals works.
class A {
String id;
public A(String id) {
this.id = id;
}
public static void main(String args[])
{
A a = new A("1");
A b = new A("1");
System.out.println(a.id);
System.out.println(b.id);
System.out.println(a.equals(b));
}
}
Result is:
1
1
false
But I want to have a.equals(b) == true why it is false?
Your class currently extends only Object class and in Object class equals method looks like this
public boolean equals(Object obj) {
return (this == obj);
}
What you need is to override this method, for example like this
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (id == other.id)
return true;
if (id == null)
return false;
if (other.id == null)
return false;
if (!this.id.equals(other.id))
return false;
return true;
}
Also when you override equals you probably should override hashCode method, but this is not subject of your question. You can read more about it here.
If you don't override equals() on the object, you are comparing two different memory references. So override equals() to compare the id fields.
It overrides Object's equals method by default, it checks the "same object" rather than "same content". If you want to have a.equals(b) == true, you should override it:
#Override
public boolean equals (Object obj) {
if (obj instanceof A) {
A a = (A) obj;
if (id == null) {
return a.id == null;
} else {
return id.equals(a.id);
}
}
return false;
}
----- EDITED -----
you should rewrite an equals() method for your code, as you would a toString() method.

Eclipse equals generation: null check missing?

I let Eclipse generate the equals method for my class and it starts with:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
[...]
It seems to me, a check like if (obj == null) return false; is missing. Otherwise, if a null reference is passed to equals there will be a null pointer exception in obj.getClass(). Am I wrong or is Eclipse wrong?
Perhaps you are having an old eclipse version. My eclipse generates this:
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
You are right, if Eclipse does it that way. But it doesn't. On my machine, Eclipse Indigo / Ubuntu, given this Class:
public class Foo {
private String bar;
}
Eclipse would generate the following equals() method:
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Foo other = (Foo) obj;
if (bar == null) {
if (other.bar != null) return false;
} else if (!bar.equals(other.bar)) return false;
return true;
}
For comparison, here's the equals() method I would write for the same class (using Guava):
#Override
public boolean equals(final Object obj) {
return obj instanceof Foo ? Objects.equal(bar, ((Foo) obj).bar) : false;
// ^--- implicit null check here
}
I use this Eclipse code template to achieve this:
${:import(com.google.common.base.Objects)}
#Override
public boolean equals(final Object obj){
return obj instanceof ${enclosing_type} ? Objects.equal(${field1:field}, ((${enclosing_type}) obj).${field1}) : false;
}
#Override
public int hashCode(){
return Objects.hashCode(${field1});
}
#Override
public String toString(){
return MoreObjects.toStringHelper(this).add("${field1}", ${field1}).toString();
}
Unfortunately, I have to keep one of these around for each cardinality of fields, so I have templates named eq1 (the above), eq2, eq3, eq4 etc. It's a small nuissance, but it's still a lot better than the monster methods generated by Eclipse.
Guava docs
Yes, passing null as obj would give a NullPointerException with that code.
You indeed need a null check. My version of Eclipse generates equals methods with a null check.
if (obj) is null, the obj.getClass() will throw an NPE
It seems to me, a check like if (obj == false) return false; is missing.
Why do you want to compare object with a Boolean value? ;-)
I suppose you though about obj == null check, and that is exactly what Eclipse generates in my case:
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TestGetClass other = (TestGetClass) obj;
if (id != other.id)
return false;
return true;
}
I am using 3.7 version. Anyway, you are right... actually Eclipse... too ;-)

Categories

Resources