删除方法上的错误参数的最佳做法

时间:2009-04-08 17:33:40

标签: data-structures collections error-handling

所以我有一个名为RegionModel的抽象数据类型,它带有一系列值(Region),每个值都映射到一个索引。可以通过调用:

删除多个区域
regionModel.removeRegions(index, numberOfRegionsToRemove);

我的问题是,当索引有效时,处理呼叫的最佳方法是什么:

(0(含)与模型中的区域数量(不包括))

但numberOfRegionsToRemove无效:

(index + regionsToRemove>模型中的区域数量)

最好抛出像IllegalArgumentException这样的异常,或者只删除尽可能多的区域(从索引到模型末尾的所有区域)?

子问题:如果我抛出异常,那么单元测试的推荐方法是调用抛出异常并保持模型不变(我在这里使用Java和JUnit,但我猜这个不是Java特定的问题。)

3 个答案:

答案 0 :(得分:2)

通常,对于这样的结构,你有一个remove方法,它接受一个索引,如果该索引超出了结构中项目的范围,就会抛出异常。

话虽如此,你应该与删除单个索引的方法一致。如果它只是忽略不正确的索引,那么如果你的范围超过(或者甚至在之前开始)结构中项目的索引,则忽略它。

答案 1 :(得分:1)

我想说一个诸如illegalArgumentException之类的参数将是最好的方式。如果调用代码没有传递可行的值,那么你不一定要相信他们真的想要删除他们所做的事情。

答案 2 :(得分:1)

我同意Mitchel和casperOne - 异常最有意义。

就单元测试而言,JUnit4允许您直接处理异常: http://www.ibm.com/developerworks/java/library/j-junit4.html

您只需要传递保证会导致异常的参数,并将正确的注释(@Test(expected=IllegalArgumentException.class))添加到JUnit测试方法中。

编辑:正如Tom Martin所提到的,JUnit 4距离JUnit 3还有一个相当大的步骤。但是,也可以使用JUnit 3测试异常。这并不容易。

我测试异常的方法之一是在类本身中使用try/catch块,并在其中嵌入Assert语句。

这是一个简单的例子 - 它不完整(例如假设regionModel被实例化),但它应该得到这个想法:

public void testRemoveRegionsInvalidInputs() {
  int originalSize = regionModel.length();
  int index = 0;
  int numberOfRegionsToRemove = 1,000; // > than regionModel's current size
  try {
    regionModel.removeRegions(index, numberOfRegionsToRemove);

    // Since the exception will immediately go into the 'catch' block this code will only run if the IllegalArgumentException wasn't thrown
    Assert.assertTrue("Exception not Thrown!", false);
  }
  catch (IllegalArgumentException e) {
     Assert.assertTrue("Exception thrown, but regionModel was modified", regionModel.length() == originalSize);
  }
  catch (Exception e) {
      Assert.assertTrue("Incorrect exception thrown", false);
  }
}