正确使用断言
您能否帮助我更好地理解“断言”与“引发异常”的正确用法是什么?每种场景什么时候合适?
场景 1
代码
public Context(Algorythm algo) {
if (algo == null) {
throw new IllegalArgumentException("Failed to initialize Context");
}
this.algo = algo;
}
测试
public void testContext_null() {
try {
context = new Context(null);
fail();
} catch (IllegalArgumentException e) {
assertNotNull(e);
}
}
场景 2
代码
public Context(Algorythm algo) {
assert (algo != null);
this.algo = algo;
}
测试
public void testContext_null() {
try {
context = new Context(null);
fail();
} catch (AssertionFailedError e) {
assertNotNull(e);
}
}
Can you please help me better understand, what is an appropriate use of “assert” vs “throwing an exception? When is each scenario appropriate?
Scenario 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);
}
}
Scenario 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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
与断言的主要区别是;
断言更适合在生产中关闭的测试。
如果您想要每次都检查的测试,尤其是验证输入中的数据,则应该使用每次运行的检查。
The main difference with assert is;
assert is more approriate for tests which will be turned off in production.
If you want a test which is checked every time, esp if validating data from an input, you should use the check which runs every time.
Assert 是一个宏(在 C/C++ 中,或在其他语言中是函数),用于验证给定表达式为 true 或 false,并在值为 false 时引发异常。
断言是在调试应用程序时使用的,例如当您必须检查数学表达式是否确实为您提供了适当的值,或者对象/结构成员是否不为空或缺少重要的内容等时。
异常抛出更多的是一种真正的错误处理。异常也是错误,可以停止您的应用程序,但它们被用作(比方说)应用程序的“零售版本”错误处理。这是因为可以用一些非技术消息而不是符号和内存地址来捕获异常并以不同的方式呈现给用户,而您可以将其序列化到应用程序日志中。
另一方面,断言只会停止正在运行的进程,并给您一条消息,例如“在 source_file.ext,第 X 行上断言失败。该进程将被终止”。这对用户来说并不友好:)
Assert is a macro (in C/C++, or a function in other languages) that validates a given expression as true or false, and throw an exception in case of false values.
Assert is something to use when ddebugging an application, like when you must check if a math expression really gives you an appropriate value, or if an object/structure member is not null or missing something important, and things like that.
An Exception throwing is more of a real error treatment. Exceptions are errors too and can stop your application, but they are used as the (let's say) "retail version" error treatment of the application. That's because Exceptions can be caught and taken differently to the user, with a little non-technical message instead of symbols and memory addresses, while you can just serialize that into an app log, for example.
On the other hand, asserts will just stop the running process and give you a message like "Assertion failed on source_file.ext, line X. The process will be terminated." And that's not user-friendly :)
当未能满足条件而违反了程序的完整性时,应使用assert 关键字。这些是不可恢复的错误情况。
另一方面,异常会向调用方法发出错误的存在和位置的警报,但可以由程序员自行决定处理或忽略。
测试时,如果必须满足条件才能通过测试,则应使用 Assert 函数。如果您期望在该特定测试中出现异常,JUnit 4 有一个注释来表示测试应该抛出特定异常:
The assert keyword should be used when failure to meet a condition violates the integrity of the program. These are intended to be non-recoverable error situations.
Exceptions, on the other hand, alert calling methods to the presence and location of an error but can be handled or ignored at the programmer's discretion.
When testing, you should use the Assert functions when a condition must be met for a test to pass. If you're expecting an exception in that particular test, JUnit 4 has an annotation to signify that an test should throw a particular Exception:
在测试代码之外,断言通常不是一个好主意。原因是,除非有非常的公司指导方针,否则最终总是会出现混合使用,这是很糟糕的。断言基本上有 2 个使用场景:
只要你总是按照其中一种情况,一切都很好。但是,如果您的代码库最终出现这两种情况,那么您就会陷入困境。您不想禁用遵循场景 2 的断言,并且您想要禁用遵循场景 1 的断言(并且会减慢生产代码)。该怎么办?
我使用过的大多数代码库在正常代码中使用了断言,但由于这个原因,从未最终在生产版本中禁用它们。因此,我的建议始终是在测试代码之外避免使用它们。对正常代码使用正常异常,并将额外的、可能较慢的代码(带断言)放在单独的测试代码中。
Outside of test code, asserts are generally a bad idea. the reason is that unless there are very strict company guidelines in place, you invariably end up with mixed usage, which is bad. there are basically 2 usage scenarios for assert:
As long as you always follow one of the scenarios, things are fine. however, if your code base ends up with both scenarios, then you are stuck. you have asserts which follow scenario 2 which you don't want to disable, and you have asserts which follow scenario 1 (and are slowing down your production code) which you want to disable. what to do?
most codebases which i have worked with which used asserts in normal code, never ended up disabling them in the production build for exactly this reason. therefore, my recommendation is always to avoid them outside of test code. use normal exceptions for the normal code, and stick the extra, possibly slow code (with asserts) in separate test code.