ChatGPT解决这个技术问题 Extra ChatGPT

assert vs. JUnit Assertions

Today I saw a JUnit test case with a java assertion instead of the JUnit assertions—Are there significant advantages or disadvantages to prefer one over the other?

There are absolutely factual differences between JUnit assertions and Java 'assert' keyword. This is not at all an opinion-based question.

S
Sinc

In JUnit4 the exception (actually Error) thrown by a JUnit assert is the same as the error thrown by the java assert keyword (AssertionError), so it is exactly the same as assertTrue and other than the stack trace you couldn't tell the difference.

That being said, asserts have to run with a special flag in the JVM, causing many tests to appear to pass just because someone forgot to configure the system with that flag when the JUnit tests were run - not good.

In general, because of this, I would argue that using the JUnit assertTrue is the better practice, because it guarantees the test is run, ensures consistency (you sometimes use assertThat or other asserts that are not a java keyword) and if the behavior of JUnit asserts should change in the future (such as hooking into some kind of filter or other future JUnit feature) your code will be able to leverage that.

The real purpose of the assert keyword in java is to be able to turn it off without runtime penalty. That doesn't apply to unit tests.


A
Adamski

I prefer JUnit assertions as they offer a richer API than the built-in assert statement and, more importantly do not need to be explicitly enabled unlike assert, which requires the -ea JVM argument.


-ea is always enabled in mvn test, no need for -ea. Richer api, good catch. Sometimes I think API is misused in test because it is not part of the application (a in api), I prefer to call it just richer methods.
s
starmer

When a test fails you get more infomation.

assertEquals(1, 2); results in java.lang.AssertionError: expected:<1> but was:<2>

vs

assert(1 == 2); results in java.lang.AssertionError

you can get even more info if you add the message argument to assertEquals


try assert 1==2: "1 is not 2";.
@PeterRader Try the assert keyword when -ea is not enabled. Or better yet, use JUnit assertions which always work.
@ThomasW when -ea is not enabled its not a test. JUnit asserations does not always work, they only work if you decide to use JUnit what is a framework, and in case of maven a maven dependency, a maven dependency that must be in test-scope only. We have two sides here: What do you prefer? 1st Side: Use a framework, as an dependency in test-scope only, that must be downloaded, that eclipse let you use in classes that are not in the src/main-folder but wont compile there because maven have junit only in test-scope or 2nd Side: Use the build-in stuff.
@PeterRader This question is about JUnit test cases. In that context JUnit or similar assertion class should be used, because these are always enabled. I have personally been caught out by Java 'assert' keyword not being enabled in the past, and do not believe unreliable assertions have a place in test code.
In the separate context of assertions in feature code -- important to robust programming practice, though not actually the topic of the question -- both Spring and Google Guava have assertion classes which are always enabled. I recommend generous use of these as parameter & state preconditions to ensure correctness. Beyond that, in performance-critical areas, there can be a small area where the Java assert may be preferable -- for correctness checks which would impact performance and are thus best disabled by default. However my experience is that most assertions should be always-on.
B
Bruno D. Rodrigues

I'd say use JUnit asserts in test cases, and use java's assert in the code. In other words, real code shall never have JUnit dependencies, as obvious, and if it's a test, it should use the JUnit variations of it, never the assert.


C
CheesePls

I would say if you are using JUnit you should use the JUnit assertions. assertTrue() is basically the same as assert, Otherwise why even use JUnit?


You would use JUnit for the test running framework. Asserts are really a small part of the value JUnit gives you. JUnit without Assert would require more boilerplate. assert without JUnit would require you to write a whole framework.
I was more saying if you're going to use the tool, USE THE TOOL. regular old assert statements seem a tad silly in JUnit test cases. They belong in with the actual code in my opinion.
@CheesePls "regular old assert statements" are in fact more recent than JUnit asserts.
D
Dan Coates

This may not apply if you exclusively use stuff that's shiny and new, but assert was not introduced into Java until 1.4SE. Therefore, if you must work in an environment with older technology, you may lean towards JUnit for compatibility reasons.