自定义方法的 JUnit 测试用例



我正在为初级Java开发人员的第一次工作面试做准备,现在我正在尝试学习JUnit测试用例。这是我遇到的一个例子,我必须说这对我来说真的很棘手(它是抽象代码,所以我不知道如何测试它(。

public class JuiceMaker {
  public Juice makeJuice(final List<Fruit> fruits) throws RottenFruitException {
    for (final Fruit fruit : fruits) {
      if (FruitInspector.isFruitRotten(fruit)) {
        throw new RottenFruitException(fruit.getName() + “ is rotten. Cannot make juice.”);
      }
    }
    return Juicer.juice(fruits);
  }
} 

我设法自己创建的唯一示例是这个:

JuiceMaker jm = new JuiceMaker();
@Test
public void isThrowingException() {
//when
  try {
      jm.throwsRuntime();
      Assert.fail("Expected exception to be thrown");
  } catch (RottenFruitException e) {
//then
      assertThat(e)
          .isInstanceOf(RottenFruitException.class)
          .hasMessage((fruit.getName() + " is rotten. Cannot make juice.");
  }
}

关于我可以对这段代码执行什么样的测试的任何提示?非常感谢您的帮助!

欢迎来到JUnit,祝您面试顺利!

要问的第一个问题是这个班级提供的合同是什么? 它需要一份水果清单,测试是否有任何水果腐烂,如果是这样,它会抛出异常,否则它会榨汁。 您可以假设"果汁"方法已在其他地方进行了测试。

对我来说,这表明这些测试:

  • 列出单一的好水果
  • 带有单个烂水果的列表
  • 列出几个好水果和一个烂水果
  • 空列表

您也可以测试空值和无效值,但这可能只是做得过头了。

一旦你决定了要测试什么,你就可以开始考虑实现它们了。 看起来您的实现有几个错误,但您正朝着一个好的方向前进。 您可能会发现 JUnit 的"预期"参数对于测试异常很有用。

您似乎在指示测试中的JuiceMaker实例引发异常以验证是否可以捕获它。

您必须回答自己,仅凭这一点是否会执行遍历Fruit列表和if()语句的循环。

您可以通过传递不同的列表(null,空的,没有腐烂的水果,有腐烂的水果(来更好地影响JuiceMaker.makeJuice()

这样,您就不会强制任何异常,而是导致它们 - 这会通过待测试的代码执行更多路径。

如果你练习上述场景,你应该对你的方法有一个非常不错的测试覆盖率。

希望这有帮助!

你在示例答案中提出的两个测试用例朝着正确的方向发展,但只有一半。因为这两个测试根本不测试您的"被测试类"。

合理的测试更像是:

public class JuiceMakerTest {
  private JuiceMaker underTest;
  @Before
  public void setup() { underTest = new JuiceMaker; }
  @Test(expected=RottenFruitException.class)
  public void testThrowsOnRottenFruit() {
    underTest.makeJuice(Collections.singletonList("rotten apple"));
  }
  @Test(expected=???)
  public void testWithNullList() {
    underTest.makeJuice(null);
  }
  @Test(expected=???)
  public void testWithEmptyList() {
    underTest.makeJuice(Collections.emptyList());
  }
  @Test
  public void testXyz() {
   Juice expectedResult = ...
   assertThat(underTest.makeJuice(Collections.singletonList("apple")), is(expectedResult);
  }

等等。换句话说:你遵循休的好答案;并确定调用方法的可能方法。???只是一个占位符 - 表示您应该考虑这里应该发生什么。也许您期望一个特定的例外;也许该方法返回一种特殊的空果汁...全部取决于被测方法的合同。

您可以从中得出错误条件和预期结果。然后,您至少为您收集的不同方面编写一个测试。

最新更新