开发者

Appropriate use of assert

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);
  }
}


The main difference with assert is;

  • the ability to turn on/off selected tests by class/package.
  • the error thrown.

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 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 :)


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:

@Test(expected=MyException.class)


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:

  1. extra, possibly slow tests which will be turned off in production
  2. normal, quick code sanity tests which should never be disabled (like requiring a given method parameter to be non-null)

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜