user1097772 user1097772 - 7 months ago 13
Java Question

Is using Assert.assertTrue(true); and assert Assert.fail(); good practise in JUnit testing?

Is this good or bad practise of using Assert.assertTrue(true); and Assert.fail() in JUnit testing and why?



I know there is also rule @Test (expected = Exception.class), but you can have more more than one exception which can be raised on tested method and if you don't want to have zillion testing methods for one tested method, this could be option.



The usecase is this: You test method which can raise zero, one or more exception (in example to make it simple just one) and you want to test case that the call is ok so no exception should be raised and if you get into catch block you will raise Assert.fail(); then you want test case when exception should be raised, so you call in catch block Assert.assertTrue(true); to say "Yeah this is what I wanted". And from the test you can see in one test method when it should fail and when you run the test if its really behave like you want to.

Question is: Is this good or bad practise? Why?


public void fooMethod(boolean paramenter) {
if(false) {
throw new Exception();
}
}

@Test
public void testFooMethod() {

try {
myTestedClassMock.fooMethod(true); //should not raise exception
} catch(Exception e) {
Assert.fail();
}

try {
myTestedClassMock.fooMethod(false); //should raise exception
} catch (Exception e) {
Assert.assertTrue(true);
}

}

Answer

You can always leave out Assert.assertTrue(true) because assertTrue is designed for a different purpose. It is there to check general conditions involving multiple boolean items, e.g.

Assert.assertTrue(t == null ||| minSize < 0 || t.size() > minSize);

Asserting a constant true always succeeds without a trace, so you can completely remove this line from your code. Catching situations when an expected exception is not thrown is done by placing Assert.fail(); immediately after the line of test code that must throw an exception, with a message indicating that an expected exception has not been thrown.

if you don't want to have zillion testing methods for one tested method, this could be option.

Typically, "zillion testing methods" is a better option. As an alternative, you could catch Exception or RuntimeException in your test, rather than catching each individual exception. This is a questionable practice in production code, but it is absolutely fine in the testing code when you must ensure that no exception is thrown.

However, having an Assert.fail(); is not an uncommon shortcut, and it is usually acceptable, too. It is a good idea to add a message describing the reason behind the failure, so that the people who maintain your code do not have to read through your tests to see what is going on. When you catch an exception, its message is a good candidate for the failure message of the test.

Comments