2

我想检查基类的先决条件,以便我知道子类型将始终使用有效的构造函数参数。

让我们以一个构造函数为例:

  1. 接受 2 个或更多参数
  2. 接受不同类型的参数
  3. 对于一个参数,它会执行多项检查(例如,字符串不为空且不为空)

在这种情况下,如何最好地使用 Guava 前置条件方法?

在这样的模拟示例中:(这是人为的!)

protected AbstractException(String errorMessage, Throwable errorCause) {
  super(errorMessage, errorCause);
  checkNotNull(errorMessage,
      ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
  checkArgument(!errorMessage.isEmpty(),
      ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
      "errorMessage");
  checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
      "errorCause");
}

我最终super在检查参数之前调用,因为调用super需要是方法的第一行,虽然我可以这样做super(checkNoNull(errorMessage)),但我不能使用相同的包装,checkArgument因为它返回void。所以困境是:

  • 我在哪里检查所有论点?我不想为此创建一个 Builder
  • 我如何像虚构的那样“分组”检查checkStringNotNullAndNotEmpty()
  • 我应该考虑与匹配器框架集成吗?(hamcrest,节日断言......)

我使用看起来很奇怪的 ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK 因为默认值throw不包含错误消息,所以从测试方面我无法将其识别为参数验证失败而不是“任何”NPE?

我做错了吗?

4

1 回答 1

1

这应该是一个评论,但它太长了。

  • 如果超级 ctor 不做它不应该super做的事情,那么在测试之前调用是无害的。
  • 它可以通过静态构建器方法来防止,您不需要构建器。但这不值得。
  • 我怀疑分组测试通常有用。如果是的话,那么已经有这样的方法了。但是,如果您需要两次以上这样的具体事物,请自己编写;如果经常出现,请将其作为 RFE 报告给 Guava 团队。
  • 我很确定,匹配器在这里是一种过度杀伤,因为你只是在创建一个异常,即很少使用的东西(我希望)。由于您的测试只是运行时的,因此它无法真正帮助捕获错误。如果您可以静态地确保“正确”构造的异常,那就太好了,但在纯 java 中这是不可能的。

更重要的是:您抛出的异常可能不如您在没有所有检查的情况下得到的异常。想象一下,用户提供了一个原因但没有任何消息。您认为这很糟糕,但是您将其替换为没有任何原因的 NPE。那更糟。

看看番石榴的Preconditions.format(包私有)。他们可以首先检查参数的正确数量,但他们没有。您可以提供太少或太多,这是一个错误,但忽略它是处理它的最佳方法。

于 2012-10-09T21:05:19.580 回答