JUnit4 fail () here, but where is pass ()?

There is a fail() method in the JUnit4 library. I like it, but it lacks the pass() method, which is not in the library. Why is this so?

I found out that I can use assertTrue(true) instead, but it still seems counterintuitive.

 @Test public void testSetterForeignWord(){ try { card.setForeignWord(""); fail(); } catch (IncorrectArgumentForSetter ex){ } // assertTrue(true); } 
+58
java junit
Oct 27 '10 at 17:53
source share
7 answers

Until the test throws an exception, it passes, unless the @Test annotation indicates the expected exception. I believe that pass() may raise a special exception, which JUnit always interprets as passing in order to short-circuit the test, but this would be contrary to the usual test design (i.e. Assuming success and only fail if the statement fails) if people realized that it is preferable to use pass() , this will significantly slow down the large set of tests (due to the overhead of creating exceptions). Failure tests should not be the norm, so it doesn’t matter much if they have overhead.

Please note that your example can be rewritten as follows:

 @Test(expected=IncorrectArgumentForSetter.class) public void testSetterForeignWord("") throws Exception { card.setForeignWord(""); } 

In addition, you must endorse the use of standard Java exceptions. Your IncorrectArgumentForSetter should probably be an IllegalArgumentException .

+58
Oct 27 2018-10-27
source share

Calling the return statement at any time when your test is complete and passed.

+59
Oct 27 '10 at 18:37
source share

I think this question needs an updated answer, since most of the answers here are pretty outdated.

Firstly, the OP question:

I think he pretty well agreed that introducing the concept of expected excepetion into JUnit was a bad move, as this exception could be raised anywhere and it would pass the test. It works if you throw (and claim) very domain-specific exceptions, but I only throw those exceptions when I work on code that should be absolutely flawless - almost APIS will just throw inline exceptions like IllegalArgumentException or IllegalStateException . If the two calls you make can raise these exceptions, then the @ExpectedException annotation will @ExpectedException green test, even if its incorrect line throws an exception!

In this situation, I wrote a class that I am sure many others here wrote that the assertThrows method:

 public class Exceptions { private Exceptions(){} public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){ try{ actionThatShouldThrow.run(); fail("expected action to throw " + expectedException.getSimpleName() + " but it did not."); } catch(Exception e){ if ( ! expectedException.isInstance(e)) { throw e; } } } } 

this method simply returns if an exception is thrown, which allows you to make further statements / checks in your test.

with java 8 syntax, your test looks very nice. Below is one of the simple tests of our model, which uses the method:

 @Test public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() { //setup AxisRange range = new AxisRange(0,100); //act Runnable act = () -> range.setLowerBound(200); //assert assertThrows(IllegalArgumentException.class, act); } 

these tests are a little mediocre because the act step does not actually do anything, but I think the meaning is still pretty clear.

There is also a small small library on maven called catch-exception that uses the mockito style syntax to verify that exceptions are thrown. It looks beautiful, but I'm not a fan of dynamic proxies. However, the syntax is so smooth that it remains enticing:

 // given: an empty list List myList = new ArrayList(); // when: we try to get the first element of the list // then: catch the exception if any is thrown catchException(myList).get(1); // then: we expect an IndexOutOfBoundsException assert caughtException() instanceof IndexOutOfBoundsException; 

Finally, for the situation that I encountered, in order to switch to this thread, there is a way to ignore tests if some conidation is performed.

I'm currently working on getting some DLLs called through a java library loaded via JNA, but our build server is located in ubuntu. I like trying to control this development with JUnit tests - even if they are far from “units” at this point. What I want to do is run the test if I'm on the local machine, but ignore the test if we're on ubuntu. In JUnit 4, there is a condition for this called Assume :

 @Test public void when_asking_JNA_to_load_a_dll() throws URISyntaxException { //this line will cause the test to be branded as "ignored" when "isCircleCI" //(the machine running ubuntu is running this test) is true. Assume.assumeFalse(BootstrappingUtilities.isCircleCI()); //an ignored test will typically result in some qualifier being put on the results, //but will also not typically prevent a green-ton most platforms. //setup URL url = DLLTestFixture.class.getResource("USERDLL.dll"); String path = url.toURI().getPath(); path = path.substring(0, path.lastIndexOf("/")); //act NativeLibrary.addSearchPath("USERDLL", path); Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class); //assert assertThat(dll).isNotNull(); } 
+4
Nov 06
source share

I was looking for the pass method for JUnit so that I could short out some tests that were not applicable in some scenarios (there are integration tests, not pure unit tests). So bad he’s not there.

Fortunately, there is a way to conditionally ignore the test, which is actually suitable for my case using the assumeTrue method:

Assume.assumeTrue (isTestApplicable);

So, here the test will be executed only if isTestApplicable is true, otherwise the test will be ignored.

+3
Jul 21 '16 at 15:12
source share

There is no need for the pass method, because if the AssertionFailedException is not thrown from the test code, the unit test event will occur.

The fail () method actually throws an AssertionFailedException to fail in testCase if the control comes to this point.

+2
Oct 27 '10 at 18:11
source share

I think this question is the result of a little misunderstanding of the test execution process. In JUnit (and other testing tools), the results are calculated by the method, not by request. There is no counter that keeps track of how many missed / failed assertX was executed.

JUnit executes each test method separately. If the method returns successfully, then the test is registered as "passed". If an exception occurs, then the test is recorded as a “failure”. In the latter case, two subheadings are possible: 1) exception of the JUnit statement, 2) any other exceptions. In the first case, the state will be “unsuccessful”, and in the second case, “error”.

In the Assert class, many shorthand methods are available to throw exceptions for approval. In other words, Assert is an abstraction layer over JUnit exceptions.

For example, this is the source code for assertEquals on GitHub :

 /** * Asserts that two Strings are equal. */ static public void assertEquals(String message, String expected, String actual) { if (expected == null && actual == null) { return; } if (expected != null && expected.equals(actual)) { return; } String cleanMessage = message == null ? "" : message; throw new ComparisonFailure(cleanMessage, expected, actual); } 

As you can see, in case of equality nothing happens, otherwise the exception will be thrown.

So:

 assertEqual("Oh!", "Some string", "Another string!"); 

just throws a ComparisonFailure exception that will be caught by JUnit and

 assertEqual("Oh?", "Same string", "Same string"); 

NOTHING.

In general, something like pass() would not make any sense, because it did nothing.

+1
Apr 03 '16 at 20:17
source share

Everything passes, and the tests must pass ...

0
Dec 20 '18 at 11:21
source share



All Articles