适当使用断言

时间:2010-12-03 15:44:27

标签: java junit assert

你能帮助我更好地理解,“断言”与“抛出异常”的适当用法是什么?每种情况何时适当?

情景1

CODE

public Context(Algorythm algo) {
  if (algo == null) {
      throw new IllegalArgumentException("Failed to initialize Context");
  }
  this.algo = algo;
}

TEST

public void testContext_null() {
  try {
      context = new Context(null);
      fail();
  } catch (IllegalArgumentException e) {
      assertNotNull(e);
  }
}

场景2

CODE

public Context(Algorythm algo) {
  assert (algo != null);
  this.algo = algo;
}

TEST

public void testContext_null() {
  try {
      context = new Context(null);
      fail();
  } catch (AssertionFailedError e) {
      assertNotNull(e);
  }
}

4 个答案:

答案 0 :(得分:5)

与assert的主要区别在于:

  • 能够按类/包开启/关闭所选测试。
  • 抛出的错误。
对于将在生产中关闭的测试,断言更为合适。

如果您想要每次都检查一次测试,例如,如果验证来自输入的数据,您应该使用每次运行的检查。

答案 1 :(得分:1)

Assert是一个宏(在C / C ++中,或在其他语言中的函数),它将给定表达式验证为true或false,并在false值的情况下抛出异常。

断言是ddebugging应用程序时要使用的东西,比如当你必须检查数学表达式是否真的给你一个合适的值,或者一个对象/结构成员是否为空或缺少某些重要的东西时,以及类似的东西。

异常抛出更多是一种真正的错误处理。例外也是错误并且可以停止您的应用程序,但它们被用作应用程序的(假设)“零售版本”错误处理。这是因为可以使用一些非技术性消息而不是符号和内存地址来捕获异常并以不同方式对用户进行捕获,例如,您可以将其序列化为应用程序日志。

另一方面,断言将停止正在运行的进程并给你一条消息,例如“在source_file.ext,X行上断言失败。该进程将被终止。”这不是用户友好的:)

答案 2 :(得分:0)

当无法满足条件时,应使用assert关键字违反程序的完整性。这些是不可恢复的错误情况。

另一方面,例外情况是警告调用方法以显示错误的存在和位置,但可以由程序员自行决定处理或忽略。

测试时,如果必须满足条件才能通过测试,则应使用Assert函数。如果您期望在该特定测试中出现异常,则JUnit 4具有注释以表示测试应该抛出特定的异常:

@Test(expected=MyException.class)

答案 3 :(得分:0)

在测试代码之外,断言通常是一个坏主意。原因是,除非有非常严格的公司准则,否则你总是会混淆使用,这很糟糕。 assert基本上有两种使用场景:

  1. 额外的,可能是慢速测试,将在生产中关闭
  2. 正常的快速代码健全性测试,永远不应该禁用(比如要求给定的方法参数为非null)
  3. 只要你总是遵循其中一个场景,事情就好了。但是,如果您的代码库最终导致两种情况,那么您就会陷入困境。你有跟随方案2的断言,你不想禁用它,并且你有跟随你想要禁用的方案1(并且正在减慢你的生产代码)的断言。该怎么办?

    我使用过的大多数代码库都使用了普通代码中的断言,从来没有因为这个原因而在生产构建中禁用它们。因此,我的建议总是在测试代码之外避免它们。使用普通代码的正常异常,并将额外的,可能很慢的代码(带有断言)粘贴在单独的测试代码中。