【问题标题】:Unit testing a method that returns the smallest value of an array单元测试返回数组最小值的方法
【发布时间】:2016-06-03 20:27:36
【问题描述】:

我有一个理论问题。给定一个方法:

public int findSmallestArrayValue(int[] values){

    int smallest = values[0];

    for (int count = 0; count < values.length; count++){

        if(values[count] < smallest){
            smallest = values[count];
        }
    }

    return smallest;
}

您可能会在这里进行哪些单元测试?到目前为止,我想出了:

    assertEquals(array.findSmallestArrayValue(new int[]{5,11,3,6,8}),3);
    assertEquals(array.findSmallestArrayValue(new int[]{5,5,5,5,5}),5);
    assertEquals(array.findSmallestArrayValue(new int[]{-1,2,3,4,5}),-1);

现在我问自己,还有什么有用/可能的?例如我想出了:

  • 大于 int 的值,但 Java 不允许我这样做?
  • 空数组,怎么办?
  • 用比 int 更多的值填充 int 数组?

特别是什么是真正有用的,什么不是?你怎么看?

【问题讨论】:

  • 对于空数组,可以使用new int[0]。我也会测试无效的可能性。
  • 您没有正确处理空数组(或 null 之一):它会引发异常。请记住,您无法测试所有内容,因此,您应该测试一些正常情况和限制情况(例如空数组)。然而,过度测试你的代码弊大于利,尤其是对于简单的函数
  • 什么意思:assertNull(array.findSmallestArrayValue(new int[]{})); ?
  • 面试题对吧?
  • 是的。但是面试已经结束了,我只是很好奇如何做到这一点;-)

标签: java arrays unit-testing automated-tests


【解决方案1】:

到目前为止,您当前的测试想法很好。这是我会考虑添加的其他测试

@Test(expected = IllegalArgumentException.class)
public void emptyArrayIsNotAcceptedArgument() {
    array.findSmallestArrayValue(new int[]{});
}

@Test(expected = IllegalArgumentException.class)
public void nullArrayIsNotAcceptedArgument() {
    array.findSmallestArrayValue(null);
}

@Test
public void lastValueIsSmallest() {
    assertEquals(array.findSmallestArrayValue(new int[]{0,-1}),-1);
}

至于你的想法:

  • 值大于 int,但 Java 不允许我这样做?
    • Java 的编译器不允许您向该方法传递除 int[] 以外的任何内容,因此无需测试
  • 用比 int 可以接受的更多的值填充 int 数组?
    • Java 数组的大小不能大于最大 int 值。无论如何,这不会真正为您的测试增加太多好处。

【讨论】:

  • 嗨,编译器告诉我应该是 ArrayIndexOutOfBoundsException 和 NullPointerException,用它​​们试了一下,它可以工作...
  • 当然...但是我建议您修改方法以在这些情况下抛出 IllegalArgumentException。当前实现引发的异常并不适合输入。
  • 嗯,比如:if (values == null) { throw new IllegalArgumentException("The array is null"); } else if (values.length == 0) { throw new IllegalArgumentException("The array is empty"); } ?我仍然得到 NullPointerException ...
  • 我傻了,设置数组 0 然后跳转到 if/else ;-)
  • 抱歉没有及时回复。是的,问题是您在检查它是否为空之前使用了该数组。始终首先检查最重要的先决条件:)。
【解决方案2】:

想到的一些案例:

  • (您的建议)检查空数组
    • values.length &gt; 0
  • 检查空数组
    • values != null

您将在方法中处理这些情况,并确保该方法输出您写入的正确错误消息或异常。

【讨论】:

    【解决方案3】:

    您总是想测试边界条件。所以你会想要测试:

    • 一个
    • 几个
    • 所有底片
    • 正面和负面的混合

    您拥有其中的一些,而其他人则提供了其他。请记住,进行这样的测试:

    assertEquals(array.findSmallestArrayValue(new int[]{5,11,3,6,8}),3);
    

    这样的测试几乎没有什么价值:

    assertEquals(array.findSmallestArrayValue(new int[]{5,11,6,8}),5);
    

    现在,当您确实遇到方法中的缺陷时,您将需要编写一个测试来公开该缺陷的条件。

    【讨论】:

      【解决方案4】:

      太棒了!感谢您的回答,我很感激!我认为一个好的组合是关键:

      public class ArrayValuesTest {
      
      ArrayValues array = new ArrayValues();
      
      @Test
      public void returnsSmallestValue() {
      
          assertEquals(array.findSmallestArrayValue(new int[]{5,11,3,6,8}),3);
          assertEquals(array.findSmallestArrayValue(new int[]{5}),5);
          assertEquals(array.findSmallestArrayValue(new int[]{0}),0);
          assertEquals(array.findSmallestArrayValue(new int[]{-5,-8,-3,-6,-11}),-11);
          assertEquals(array.findSmallestArrayValue(new int[]{-20,11,-3,6,-8}),-20);
      
      }
      
      @Test(expected = ArrayIndexOutOfBoundsException.class)
      public void emptyArrayIsNotAcceptedArgument() {
          array.findSmallestArrayValue(new int[]{});
      }
      
      @Test(expected = NullPointerException.class)
      public void nullArrayIsNotAcceptedArgument() {
          array.findSmallestArrayValue(null);
      }
      

      }

      您认为在第一个测试方法中包含多个断言而不是使用单独的测试方法是不好的做法吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-23
        • 2022-07-27
        相关资源
        最近更新 更多