英文:
Getting full branch coverage in equals() method with EclEmma
问题
这很繁琐,但我有一个作业,我需要实现equals()方法的完全覆盖,以获得所有可能的分数。由于equals()方法中getClass()部分的存在,我在实现全语句/分支覆盖方面遇到了问题。到目前为止,我已经覆盖了1/2个分支,但我无法理解如何进入第二个分支。
以下是equals()方法:
public boolean equals(Object obj) {
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
//许多其他测试,检查我已经找出的程序功能
return true;
}
导致我覆盖了1/2个分支的单元测试:
assertFalse(!s1.getClass().equals(s1.getClass()));
既然我已经覆盖了1/2个分支,我认为第二个分支也是可能的。但我不确定。
谢谢
英文:
This is tedious, but I've got an assignment where I need to achieve full coverage of the equals() method to earn all possible points. I'm having issues getting full statement/branch coverage due to the getClass() portion of the equals() method. So far I've gotten 1/2 branches covered, but I can't get my mind around how to get to the second.
Equals method below:
public boolean equals(Object obj) {
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
//Lots of other tests checking the functionality of the program that I've figured out already
return true;
}
The unit test that is getting me 1/2 branches covered:
assertFalse(!s1.getClass().equals(s1.getClass()));
Since I've gotten 1/2 branches covered I assume the second is possible. But idk.
Thanks
答案1
得分: 0
if (getClass() != obj.getClass()) return false;
将考虑两个实例在不是同一个类的实例时视为不同。例如,当obj
是一个扩展了this
类的类的实例时,即使所有字段具有相同的值。
因此,您还必须将s1
与扩展了s1
类的类的实例s2
进行比较,以使得这里的return false;
分支被执行。
请注意,在assertFalse(!s1.getClass().equals(s1.getClass()));
中,不会调用您的equals
方法,而会调用java.lang.Class::equals
方法,而且assertFalse(!...)
与assertTrue(...)
是相同的。
英文:
if (getClass() != obj.getClass()) return false;
considers two instances to be different if both are not instances of the same class. For example, when obj
is an instance of a class that extends the class of this
, even if all fields have the same value.
So you also have to compare s1 with a s2, that is an instance of a class that extends the class of s1 to get here the return false;
branch executed.
Please note, that in assertFalse(!s1.getClass().equals(s1.getClass()));
your equals
method is not called, but java.lang.Class::equals
and that assertFalse(!...)
is the same as assertTrue(...)
.
答案2
得分: 0
你遗漏的一些信息是"s1"对象属于哪个类,以及这个"equals"方法在哪个类中。合理的假设是"s1"与你所定义"equals"方法的类具有相同的类型。
在这个假设下,你所关注的那行代码(根据@howlger提到的简化版本):
assertTrue(s1.getClass().equals(s1.getClass()));
实际上并没有执行你的"equals"方法。这是因为你调用的是"s1.getClass().equals(...)"而不是"s1.equals(...)"。
一个真正测试你代码的断言应该更像这样:
assertTrue(s1.equals(s1));
针对你覆盖率的问题,这单独的断言并不能让你在方法中获得完整的覆盖率。它只会匹配第一个"if"语句并返回true。
以下断言将让你更接近完整的覆盖率:
// s1和s2是同一类的不同实例,但内容相同
assertTrue(s1.equals(s2));
// s1和s2是同一类的不同实例,内容不同
assertFalse(s1.equals(s2));
// s1和s2是不同类的实例
assertFalse(s1.equals(s2));
此外,值得注意的是,你可以在调试器中运行测试,设置断点在"equals"方法中,以验证代码的执行路径。
英文:
Some information you've left out is what class the "s1" object is, and what class this equals method is in. It's reasonable to assume that "s1" is of the same type as the class your "equals" method is defined in.
Under that assumption, the line in question (converted to the simpler version alluded to by @howlger):
assertTrue(s1.getClass().equals(s1.getClass()));
Is not even executing your "equals" method. That's because you're calling "s1.getClass().equals(...)" instead of "s1.equals(...)".
An assertion that would actually be testing your code would be more like this:
assertTrue(s1.equals(s1));
To address your coverage question, this obviously by itself would not give you full coverage in the method. It will match the first "if" and return true.
Assertions that should give you closer to complete coverage would include these:
// s1 and s2 are different instances of the same class, with identical contents
assertTrue(s1.equals(s2));
// s1 and s2 are different instances of the same class, with different contents
assertFalse(s1.equals(s2));
// s1 and s2 are different instances of different classes
assertFalse(s1.equals(s2));
In addition, it's useful to note that you can run your test in the debugger, with breakpoints in the "equals" method, to verify exactly what path the code takes.
专注分享java语言的经验与见解,让所有开发者获益!
评论