In said:
Do you think you found a bug?
Do you have a test that demonstrates it?
Yes, but it might be just a misunderstanding about what
appendTo() and equals() are supposed to do. Make a MoneyBag
with 5 CHF and 5 USD. Make a Money with -5 CHF. Append the
latter to the former with a call to appendTo(). If I assume the
correct intended specification for appendTo(), we should get
something with just 5 USD. However, the result is not equal to
a Money with just 5 USD in it. Here's the code.
public class MoneyBug {
public static void main(String[] args) {
MoneyBag moneyBagTarget = (MoneyBag)
MoneyBag.create(new Money(5, "CHF"), new Money(5, "USD"));
Money minusFiveFrancs = new Money(-5, "CHF");
Money fiveBucks = new Money(5, "USD");
minusFiveFrancs.appendTo(moneyBagTarget);
if (moneyBagTarget.equals(fiveBucks)) {
System.out.println("No bug");
} else { // Shouldn't they be equal?
System.out.println("Bug");
System.out.println("moneyBagTarget: " + moneyBagTarget);
System.out.println("fiveBucks: " + fiveBucks);
}
}
}
The problem is that the MoneyBag now contains just one
currency, but MoneyBag.equals() essentially assumes that a
MoneyBag has more than one currency (it returns false if it is
being compared to a Money). Note that toString() on the
MoneyBag returns "{[5 USD]}".
Interestingly Kent Beck in _TDD By Example_ addresses a
very similar problem in his discussion of the add() method and
equals(). It is fixed there. Almost every operation ultimately
comes down to a MoneyBag.create() call, and create() calls
simplify() is called in order to make create() return a Money if
there is only one currency left. So MoneyBag.equals() assumes
that "this" has more than one currency and cannot be equal to a
Money. However, appendTo() does not always create such a MoneyBag.
appendTo() has to be an IMoney method because of the way it
is called in MoneyBag. But what is the specification? If it is
essentially supposed to add the method receiver to the method
parameter, then it is producing something of a form not expected
by equals(). This could be classified as a bug in appendTo() or
a bug in equals(). I think the easiest way to fix it is to
change equals() so that the MoneyBag "{[5 USD]}" is equal to the
Money "[5 USD]". Of course I may just have misunderstood what
appendTo() and/or equals() are supposed to do.
This bug (if it is a bug) was found using a new tool,
RUTE-J (Randomized Unit Testing Engine for Java), programmed by
my research group.
If so, you might get more interest in the JUnit discussion group:
http://groups.yahoo.com/group/junit/
I'll take a look there. Thanks!
--Jamie. (Celebrating (?) 20 years on Usenet!)
andrews .uwo } Merge these two lines to obtain my e-mail address.
@csd .ca } (Unsolicited "bulk" e-mail costs everyone.)