如何使用assertEquals编写Junit测试,以查看每个硬币将使用多少钱返回给我?

时间:2017-05-29 02:30:24

标签: java junit bigdecimal currency

我需要使用assertEquals编写一个测试,以查看在给出金钱时我会将多少硬币退还给我,并且不确定如何构建它或包含哪些信息。可以插入1美元,2美元,5美元和10美元的金额。返回的变更必须是最少的硬币。

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.";
}
}

1 个答案:

答案 0 :(得分:4)

简单地说:您必须编写可测试的代码才能测试代码。

当然,您可以从该方法返回的字符串中解析该信息。但那是错误的做法。

事情是:你的代码在这里混合了两个职责:A)计算需要返回的硬币/硬币B)将其变成人类可读的消息。

换句话说:首先编写另一个方法,该方法返回一些可以由计算机轻松测试的方法。例如,通过创建表示更改的类,例如:

public class Change {
  public int getNumberOfQuaterts() { ...
  public int getNumberOfDimes() { ...
  ...

现在你可以改变你的方法说:

public Change changeAmount(BigDecimal amtToReturn) { ...

现在测试变得非常容易:

Change change = new MakeChange().changeAmount(...
assertThat(change.getNumberOfQuarters, is(5));

除此之外:

  • 您可以在toString()类中现在 @Override Change来创建人类可读的消息。您还可以编写简单的测试用例,然后实际检查某些预定义的更改会产生一些您期望代表该对象的精确字符串。
  • 您的示例代码中存在各种问题。例如:有一个空的默认构造函数有没有点。如果构造函数无关,则不要将其写下来。并且,非常重要:您应该使用BigDecimal中带有 double 参数的构造函数。请改用BigDecimal("0.01")! (见here)。 原因为什么该构造函数为@deprecated

最后:您还可以在Change类中@Override equals(),然后测试代码可以归结为:

assertThat(underTest.changeAmount(whatever), is(new Change(....))

您可以自己手动创建允许进行相等性检查的更改对象,以便您可以使用assertThat()直接比较更改对象。