I need to write a test using assertEquals to see how many of each coins will be returned to me when money is given and am not sure how to structure it or what info to include. Money can be inserted in the amounts of $1, $2, $5 and $10. Change returned must be in the fewest amount of coins possible.
import java.math.BigDecimal;
public class MakeChange {
BigDecimal numOfQuarters = new BigDecimal(0.00);
BigDecimal numOfDimes = new BigDecimal(0.00);
BigDecimal numOfNickels = new BigDecimal(0.00);
BigDecimal quarter = new BigDecimal(0.25);
BigDecimal dime = new BigDecimal(0.10);
BigDecimal nickel = new BigDecimal(0.05);
public MakeChange() {
}
public String changeAmount(BigDecimal amtToReturn) {
while (amtToReturn.compareTo(quarter) >= 0) {
numOfQuarters = amtToReturn.divideToIntegralValue(quarter);
amtToReturn = amtToReturn.subtract(numOfQuarters.multiply(quarter));
}
while (amtToReturn.compareTo(dime) >= 0) {
numOfDimes = amtToReturn.divideToIntegralValue(dime);
amtToReturn = amtToReturn.subtract(numOfDimes.multiply(dime));
}
while (amtToReturn.compareTo(nickel) >= 0) {
numOfNickels = amtToReturn.divideToIntegralValue(nickel);
amtToReturn = amtToReturn.subtract(numOfNickels.multiply(nickel));
}
return "You will receive: " + numOfQuarters + " Quarters " + numOfDimes + " Dimes and " + numOfNickels
+ " Nickels.";
}
}
Simply spoken: you have to write testable code in order to be able to test code.
Of course, you could parse that information out of the string that this method returns. But that would be the wrong approach.
Thing is: your code is mixing two responsibilities here: A) computing how/what coins need to be returned B) turning that into a human readable message.
In other words: you start by writing another method that returns something that can easily be tested by a computer. For example by creating a class that represents change, like:
public class Change {
public int getNumberOfQuaterts() { ...
public int getNumberOfDimes() { ...
...
Now you could change your method to say:
public Change changeAmount(BigDecimal amtToReturn) { ...
and now testing becomes super-easy:
Change change = new MakeChange().changeAmount(...
assertThat(change.getNumberOfQuarters, is(5));
Beyond that:
toString()
in that Change
class - to create that human readable message. You can also write simple testcases then where you actually check that some predefined Change results in some exact string that you would be expecting to represent that object.BigDecimal("0.01")
instead! (see here). There is a reason why that constructor is @deprecated
!Finally: you could also @Override equals()
in the Change class, then test code could boil down to:
assertThat(underTest.changeAmount(whatever), is(new Change(....))
You can enable yourself to manually create change objects that allow for equality checks, so that you can use assertThat()
to compare change objects directly.