我如何使用 assertEquals 编写一个 Junit 测试来查看每个硬币中有多少会返回给我?

How can I write a Junit test using assertEquals to see how many of each coins will be returned to me using?

我需要使用 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.";
}
}

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

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

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

换句话说:您首先要编写 另一个 方法,returns 一些可以很容易地由计算机测试的方法。例如,通过创建代表变化的 class,例如:

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

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

public Change changeAmount(BigDecimal amtToReturn) { ...

现在测试变得超级简单:

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

除此之外:

  • 您可以现在 @Override toString() Change class - 来创建人类可读的消息。您还可以编写简单的测试用例,然后在其中实际检查某些预定义的 Change 是否会产生您期望代表该对象的确切字符串。
  • 您的示例代码中存在各种 问题。例如:no 有一个空的默认构造函数。如果构造函数无事可做,那就不要写下来。而且,真的很重要:你应该使用BigDecimal中的构造函数,它接受一个double参数。请改用 BigDecimal("0.01")! (参见 here)。有一个 原因 为什么构造函数是 @deprecated!

最后:你也可以在 Change class 中 @Override equals(),然后测试代码可以归结为:

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

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