2010-12-03 52 views
1

你能帮我更好地理解什么是“assert”vs“抛出异常”的恰当用法?每种情况何时适合?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); 
    } 
} 
+0

您无法捕捉到空例外。 assertNotNull(e)必须为真。 – 2010-12-03 15:49:46

回答

5

与断言的主要区别是;

  • 能够打开/关闭选定的测试类/包。
  • 抛出的错误。

断言对于将在生产中关闭的测试更为合适。

如果您想要每次都检查一次的测试,尤其是如果要验证输入中的数据,则应使用每次运行的检查。

1

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

断言应用程序时使用断言,就像你必须检查数学表达式是否真的给你一个合适的值,或者如果一个对象/结构成员不是null或缺少重要的东西等等。

异常抛出更多的是一种真正的错误处理。异常也是错误,可以阻止你的应用程序,但它们被用作应用程序的“零售版本”错误处理(比方说)。这是因为Exceptions可以被捕获并以不同的方式呈现给用户,带有一些非技术性的消息而不是符号和内存地址,例如,您可以将它们序列化到应用程序日志中。

另一方面,断言会停止正在运行的进程,并为您提供一条消息,如“在source_file.ext上的断言失败,第X行,该进程将终止。”而且这不是用户友好的:)

0

当遇到不符合条件的条件违反了程序的完整性时,应该使用assert关键字。这些意图是不可恢复的错误情况。

另一方面,异常提示调用方法是否存在错误,并且可以根据程序员的判断来处理或忽略。

测试时,当测试通过时必须满足条件时才应使用Assert函数。如果你希望在特定的测试异常,JUnit 4中有一个注释,以表示一个测试应该抛出一个特殊的异常:

@Test(expected=MyException.class) 
0

的测试代码之外,断言通常是一个坏主意。原因在于,除非有严格的公司指导原则,否则你总是会混合使用,这是不好的。基本上有2个断言使用场景:

  1. 额外,可能慢测试将在生产被关闭
  2. 正常,快速编码神智其不应被禁用(例如需要一个给定的方法的参数是测试非空)

只要你总是遵循其中一个场景,事情就没有问题。然而,如果你的代码基地结束了两种情况,那么你卡住了。您已经断定了您不希望禁用的方案2后面的内容,并且您已经声明了要禁用的方案1(并且正在放慢您的生产代码)。该怎么办?

大多数我使用过的正常代码中声明的代码库,从来没有因为这个原因而停止在生产版本中禁用它们。因此,我的建议总是在测试代码之外避免它们。使用普通代码的正常例外,并将额外的,可能较慢的代码(使用断言)粘在单独的测试代码中。