I am trying to test if a method throws a IllegalArgumentException in Junit with the code below, however it didn't work. Eclipse suggested to create an annotation class, which confuses me a bit. Can I get away without using an annotation? Otherwise what's the best solution for this?
#Test(expected = IllegalArgumentException.class)
public void testRegister(){
myProgram.register(-23); //the argument should be positive
}
I usually try catching the Exception I'm interrested in, and pass the test if it's caught. Try something like this:
try {
myProgram.register(-23);
// (optional) fail test here
}
catch (IllegalArgumentException e){
// pass test here
}
catch (Exception e) {
// (optional) fail test here
}
If you don't want to use an annotation you can catch all exceptions and test in an assertion that the exception is of instance IllegalArgumentException.
Exception e = null;
try {
// statement that should cause exception
} catch(Exception exc) {
e = exc;
}
// Assert that e is not null to make sure an exception was thrown
// Assert that e is of type IllegalARgumentException
But in the end it is much simpler to just use the JUnit annotation. Which seems to be correct to me.
Related
For eg.
try {
// Some code
}
catch (IOException e) {
throw new CustomDefineException(e);
}
I want to write mockito coverage statement for the catch block. How can that be done? I'm new on mockito framework.
So basically as per Joni, we can only test the catch block, when there is actually an exception that is occurring, till then it cannot be tested.
You can write the test cases that actually make the code to throw exception.
The control would go to the Catch Block and your coverage would increase.
For the test case to pass you can write the test case that would expect to get exception like
#Test(expected = CustomDefineException.class)
public void shouldThrowCustomDefineExceptionWhenWrongParameterIsSupplied() {
// Your Logic to create Exception
}
on the top of the test Method.
For example, if I have something like this:
try {
// db call
} catch ( Exception e ) {
return false
}
I want to write a unit test to test this method. How should I write that? Or to say it differently, what will be an example of code that will cause SQLException or any other exception to be thrown?
We usually write such a test code like this:
try {
// Do something you expect to fail.
Assert.fail();
} catch (SQLException e) { // Expected exception type.
Assert.assertEquals(e.getMessage(), "Expected message");
// Or alternatively.
Assert.assertTrue(e.getMessage().startsWith("Expected start of the message"));
}
The Assert.fail() part makes sure that the test fails in case the code did not throw the error.
We all write from time to time code like this:
try {
// ... some code.
} catch (SomeException e) {
// ... No action is required, just ignore.
}
Is there any standard code fragment like annotation to show we really intend to ignore exception? Something that shows to other team members and static analyzers we really need to skip this situation like InterruptedException after Thread.sleep()? Something like:
Exception.ignore(e);
Googled around but have not found something standard for such case.
This is especially relevant to tests that assure exceptions:
try {
action();
fail("We expected this to fail.");
} catch (ExpectedException e) {
ignore(e, "OK, so far so good.");
}
The only way to ignore an exception is to catch & swallow it, being very specific on the exception of course, you wouldn't want to catch Exception e, that would be a very bad idea.
try{
... //code
}
catch( VerySpecificException ignore){
Log(ignore);
}
Logging is obviously optional but a good practice.
in order to keep the code up with your exception handling or ignoring, it's nice to name the exception var as ignored:
try {
action();
} catch (ExpectedException ignored ) {}
Concerning your update referring to testing, if you use a testing framework, you can annotate the test in such a way that an exception is expected, e.g. using TestNG
#Test(expectedExceptions = ClassNotFoundException.class)
public void testSomething() {
// will succeed if a ClassNotFoundException is thrown
}
I have a code segment like shown below. Each line of code throw same exception. However, in practice, when first line throws an exception, testFoo finishes its job and does not continue, as expected. But, I want a bit more different thing; since they are throwing same exception, I want to continue and check these three lines w.r.t the exception which they all throw. If they throw, test should be continue.
How can I test these three line w.r.t same exception?
#test
void testFoo(){
assertNull( /*errorMessage*/, ClassFoo.foo(null)); // foo will throw `AssertionError` due to null parameter
assertNull( /*errorMessage*/, ClassBar.bar(null)); // foo will throw `AssertionError` due to null parameter
assertNull( /*errorMessage*/, ClassGbr.gbr(null)); // foo will throw `AssertionError` due to null parameter
}
Just catch the exception yourself:
#Test
void testFoo() {
boolean fooHasThrownException = false;
boolean barHasThrownException = false;
boolean gbrHasThrownException = false;
try {
ClassFoo.foo(null);
fail();
} catch (AssertionError e) {
fooHasThrownException = true;
}
try {
ClassBar.bar(null);
fail();
} catch (AssertionError e) {
barHasThrownException = true;
}
try {
ClassGbr.gbr(null);
fail();
} catch (AssertionError e) {
gbrHasThrownException = true;
}
assertThat(true, equalTo(fooHasThrownException),
equalTo(barHasThrownException),
equalTo(gbrHasThrownException));
}
Note that your assertNull() is redundant. If a method throws an exception, it will not return anything.
On the side, this is a very weird scenario to be testing. If a method throws an exception, it just seems more logical to stop any further processing, if those processes down the line are going to also throw exceptions anyway.
I have tried to implement precondition for each parameters to a method with Java built-in Assert.assertTrue...
This is not built into java, this is from junit: void junit.framework.Assert.assertTrue(...). You are confusing Java Assertions with Junit assertions.
Junit assertions should be used in your unit tests. They look like Assert.assertEquals(result, "expected result"); They are intended to test the validity of the methods under test in your unit tests.
Java assertions should be used when verifying assumptions. They look like assert param!=null:"param should not be null!"; They are part of the java language and can be turned on and off at compile time. They are intended to double check assumptions in your code and to produce zero overhead when turned off.
Programming with assertions is a great thing. Using Junit assertions outside of unit tests is dubious.
My interpretation of this question is that you are expecting an AssertFailedError in your unit test and this is meant to be part of this test. If that is the case, you can use the following junit method structure:
#Test(expected = AssertFailedError.class)
public void testFoo() throws AssertFailedError
{
assertNotNull(null);
}
You can use this when you are testing a block of code that you know will throw an exception.
I have this unit test, that the overall test fails because of the exceptions that is thrown, although its expected:
#Test(expected = AutoGenerateStringIdException.class)
public void testPut_shouldThrowException(){
RootEntity rootObject = new RootEntity();
// Some codes here
try {
Key key = store.put(rootObject);
} catch(AutoGenerateStringIdException e){
assertEquals(e.getMessage(), "Cannot auto-generate String #Id");
}
}
You can either have #Test(expected = SomeException.class) or use a try...catch as you're doing. You can't use both of them at the same time.
When you declare a test to expect a certain exception to be thrown and if you catch it within the test, it wouldn't be thrown, would it?
Although I haven't tried it, you could try re-throwing the exception from the catch block.
catch(AutoGenerateStringIdException e){
assertEquals(e.getMessage(), "Cannot auto-generate String #Id");
throw e;
}
Please have a look at the JUnit wiki: https://github.com/junit-team/junit/wiki/Exception-testing It lists different approaches for testing exceptions.
If exception is expected in test, you should not catch it. Just remove try/catch and watch, what happens.