【发布时间】:2023-03-24 12:57:01
【问题描述】:
我正在与一位同事就我遇到的特定情况进行辩论, 如果有人能提出一些观点或理论基础,那就太好了。
假设我们有类型 A 的模型对象。它们是 java bean、属性持有者、 并拥有 getPrice、getQuantity、getName 等方法。
我们还假设由于某些遗留原因,equals 方法返回 true, 在两个不同的对象上,即使它们具有不同的属性值!
我将提供一些代码来说明这个问题。 (显然代码不一样,走捷径)
class A {
private final double q;
private final double p;
public A(double q, double p) {
this.q = q;
this.p = p;
}
public double getQuantity()
{
return q;
}
public double getPrice()
{
return p;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
// not the actual method but a.equals(aWithDifferentValues) is True
// this is the crux of the problem
return true;
}
}
public abstract class Handler {
protected Manager m;
public Handler(Manager m) {
this.m = m;
}
abstract public void handle(A a);
}
class HandlerA extends Handler {
public HandlerA(Manager m) {
super(m);
}
@Override
public void handle(A a) {
m.f(a, "abc");
}
}
...
class HandlerC extends Handler {
public HandlerC(Manager m) {
super(m);
}
@Override
public void handle(A a) {
m.g(a, 1);
}
}
class Manager {
public void f(A a, String s) { }
public void g(A a, double q) { }
}
我们要对 HandlerA 进行单元测试。
所以我们可能想写一个这样的测试:
public class TestMain {
@Test
public void givenA_fHappens() {
Manager manager = mock(Manager.class);
HandlerA handler = new HandlerA(manager);
A givenA = new A(7, 9);
handler.handle(givenA);
verify(manager).f(givenA, "abc");
}
}
现在问题出现了,因为equals返回true,对于具有不同属性的不同A对象在代码中进行此修改:
@Override
public void handle(A a) {
-- m.f(a, "abc");
++ m.f(new A(1, 1), "abc");
}
不会被单元测试覆盖
我建议我们在验证中使用匹配器,(或在有参数捕获者的地方断言) 事实上,已经有一个名为SamePropertyValueAs 的服务可以提供服务, 但有人批评说我们不想断言它们具有相同的值,只是调用了代码。
你怎么看?您对此有何看法?
【问题讨论】:
标签: java unit-testing tdd mockito hamcrest