JUnit test case for Java Runnable run - java

I want my program to run fine even though there is an exception. The following does that. Can someone help me writing JUnit test case for this?
protected static Runnable myMethod=new Runnable() {
#Override
public void run() {
try {
//my code - may raise exception
} catch (Throwable t) {
logger.error("Exception occured", t.getMessage());
}
}
};

Throwing an exception up from a #Test method will cause it to end with an error, which isn't a success. So the textbook approach for such cases is to just set up the conditions, run the method, and assume everything is OK if an exception doesn't cause the test to error:
#Test
public void testMyLogic() {
// Set up conditions that would cause an the Runnable's body to throw an exception
myMethod.run();
// If we got here an exception was NOT thrown.
// Implicitly, we're OK.
}

Related

Java Eclipse - JUnit test expects exception but still fails when exception is [duplicate]

I wrote some test cases to test some method. But some methods throw an exception. Am I doing it correctly?
private void testNumber(String word, int number) {
try {
assertEquals(word, service.convert(number));
} catch (OutOfRangeNumberException e) {
Assert.fail("Test failed : " + e.getMessage());
}
}
#Test
public final void testZero() {
testNumber("zero", 0);
}
If I pass -45, it will fail with OutOfRangeException but I am not able to test specific exception like #Test(Expected...)
An unexpected exception is a test failure, so you neither need nor want to catch one.
#Test
public void canConvertStringsToDecimals() {
String str = "1.234";
Assert.assertEquals(1.234, service.convert(str), 1.0e-4);
}
Until service does not throw an IllegalArgumentException because str has a decimal point in it, that will be a simple test failure.
An expected exception should be handled by the optional expected argument of #Test.
#Test(expected=NullPointerException.class)
public void cannotConvertNulls() {
service.convert(null);
}
If the programmer was lazy and threw Exception, or if he had service return 0.0, the test will fail. Only an NPE will succeed. Note that subclasses of the expected exception also work. That's rare for NPEs, but common with IOExceptions and SQLExceptions.
In the rare case that you want to test for a specific exception message, you use the newish ExpectedException JUnit #Rule.
#Rule
public ExpectedException thrown= ExpectedException.none();
#Test
public void messageIncludesErrantTemperature() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("-400"); // Tests that the message contains -400.
temperatureGauge.setTemperature(-400);
}
Now, unless the setTemperature throws an IAE and the message contains the temperature the user was trying to set, the test fails. This rule can be used in more sophisticated ways.
Your example can best be handled by:
private void testNumber(String word, int number)
throws OutOfRangeNumberException {
assertEquals(word, service.convert(number));
}
#Test
public final void testZero()
throws OutOfRangeNumberException {
testNumber("zero", 0);
}
You can inline testNumber; now, it does not help much. You can turn this into a parametrized test class.
Remove the try-catch block and add throws Exception to your test method, like:
#Test
public final void testZero() throws Exception {
assertEquals("zero", service.convert(0));
}
JUnit expects failing tests will throw Exceptions, your catching them is just stopping JUnit from being able to report them properly. Also this way the expected property on the #Test annotation will work.
You don't need to catch the exception to fail the test. Just let it go (by declaring throws) and it will fail anyway.
Another case is when you actually expect the exception, then you put fail at the end of try block.
For example:
#Test
public void testInvalidNumber() {
try {
String dummy = service.convert(-1));
Assert.fail("Fail! Method was expected to throw an exception because negative numbers are not supported.")
} catch (OutOfRangeException e) {
// expected
}
}
You can use this kind of test to verify if your code is properly validating input and handles invalid input with a proper exception.
There are several strategies that are open to you to deal with expected exceptions in your tests. I think the JUnit annotations and try/catch idiom have already been mentioned above. I'd like to draw attention to the Java 8 option of Lambda expressions.
For instance given:
class DummyService {
public void someMethod() {
throw new RuntimeException("Runtime exception occurred");
}
public void someOtherMethod(boolean b) {
throw new RuntimeException("Runtime exception occurred",
new IllegalStateException("Illegal state"));
}
}
You can do this:
#Test
public void verifiesCauseType() {
// lambda expression
assertThrown(() -> new DummyService().someOtherMethod(true))
// assertions
.isInstanceOf(RuntimeException.class)
.hasMessage("Runtime exception occurred")
.hasCauseInstanceOf(IllegalStateException.class);
}
Take a look at this blog which covers most of the options with examples.
http://blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html
And this one explains the Java 8 Lambda option more fully:
http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

Test if an exception is caught with Junit

I'll begin with a code example; I have to test a function, which handles data-packets. In this function, the data-packet is opened and when it doesn't contain all expected data, an InvalidParameterExeption is thrown which is logged.
public void handleData(dataPacket) {
try {
analyseData(dataPacket);
} catch (InvalidParameterException e) {
e.printStackTrace()
}
}
So, if everything goes well, my exception is printed in my terminal.
But how can I test this? I can't use this: (because the exception is caught)
#Test(expected = InvalidParameterExeption.class)
public void testIfFaultyDataPacketIsRecognised {
handleData(faultyDataPacket);
}
How can I test that the InvalidParameterExeption is thrown?
You won't catch exceptions that are not thrown. Just test the 'throwing exception' method instead of the 'exception catching' one
#Test(expected = InvalidParameterExeption.class)
public void testIfFaultyDataPacketIsRecognised() {
analyseData(faultyDataPacket);
}
Ideally you should catch and rethrow the exception.But if you dont want to do that then Why not get catch the exception in test case as expected?
#Test
public void testIfFaultyDataPacketIsRecognised () {
try {
handleData(faultyDataPacket);
Assert.fail("Fail! Method was expected to throw an exception because faulty data packet was sent.")
} catch (InvalidParameterException e) {
// expected
}
}

Exception at calling one program from another program inside Runnable interface

I am facing problem while I am trying to call another program from Task3 program and try to execute it on scheduled time. Getting exception at line 14 as below.
Please let me know where I am going wrong in call program from run method of Runnable interface.
Task3.java:14: error: unreported exception Exception; must be caught or declar
to be thrown
Mult.main(new String[0]);
import java.util.Timer;
import java.util.TimerTask;
public class Task3 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
Mult.main(new String[0]);
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
Mult.main has a throws clause that includes a checked exception, so for the code to be accepted by the compiler you'd need to add that exception to the throws clause of the run method or catch the exception. You can't add that exception to the throws clause however, since you override TimerTask.run, which declares no exceptions.
The only remaining opitions are catching that error or change Mult.main to not throw any exceptions that are not subclasses of RuntimeException. You could e.g. catch the exception and throw a runtime exception or do something else, if an exception occurs:
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
try {
Mult.main(new String[0]);
} catch (Exception ex) {
// handle the exception,
// in this case by throwing a RuntimeException with ex as cause
throw new IllegalStateException("I didn't expect a exception.", ex);
}
}
};
This is a compile-time error. Your method Mult.main() can throw an Exception.
Surround it with try/catch to handle error, e.g.
try {
Mult.main(new String[0]);
} catch (Exception e) {
// Handle your error here
}
It's hard to tell without more code, but it looks like:
Mult.main(...) is defined as throwing an exception, in which case the code that calls must handle the exception.
Either:
Wrap the call to Mult.main(...) in a try-catch block, or
Define Task3.main(...) to throw Exception as well
P.S. or maybe it's timer.scheduleAtFixedRate(...), can't really tell without line numbers

Sonar cannot cover branches calling to Exception throwing function

I am writing code coverage for my project and experiencing a weird behavior. I have a function like this
public void testException(int i) throws Exception {
if (i == 0) {
throw new Exception("exception");
}
}
and the test case
#Test
public void testException() {
try {
mapper.testException(0);
fail("Wrong");
} catch (Exception ex) {
assertEquals("exception", ex.getMessage());
}
}
After running test case through maven (mvn sonar:sonar), then the branch is covered in Sonar. However, if the tested function is like this
public void testException(int i) throws Exception {
if (i == 0) {
throwException();
}
}
public void throwException() throws Exception {
throw new Exception("exception");
}
then the if branch is not covered, though the inner of throwException function is actually executed. Is there anyway to overcome this problem? I need to cover 100% of the class
Look like the reason why code is not covered is in the FAQ
Code with exceptions shows no coverage. Why?
JaCoCo determines code execution with so called probes. Probes are
inserted into the control flow at certain positions. Code is
considered as executed when a subsequent probe has been executed. In
case of exceptions such a sequence of instructions is aborted
somewhere in the middle and not marked as executed.
Still i don't understand why the coverage of the direct throw still appears on sonar

Tests. Do I really need to add "throws Exception"?

I saw people using "throws Exception" in tests, but I never do. Should I worry? I never had any issues with that. What's the difference?
#Test()
public void test() throws Exception
{
//Do something
}
or
#Test()
public void test()
{
//Do something
}
If the code you are testing throws an exception, you must handle it in some way. Either by declaring a "throws Exception" in the method signature, or by using try-catch.
If the code you are calling in the method does not throw any exceptions, then you dont need either of those. The compiler will let you know if you need to catch an exception in some way.
Also note that you can do tests that makes sure an exception is thrown, see this answer
junit will mark a test as being in "error state" if an exception is thrown from that method. For most usecases, this is essentially the same as failing a test (in the sense that a test that completed in error state did not succeed). A lot of test authors don't like the hassle (or the code-uglification) associated with handling checked exceptions.
E.g., Consider a test that should run a couple of methods and assert the end state of an object:
public class SomeTest
SomeObject so;
#Before
public void setUp() {
so = new SomeObject();
}
#Test
public void TestSomeFlow() {
try {
so.init();
// must catch in order to avoid a compilation error
} catch (InitExceptionIDontCareAbout e) {
fail ("init failed");
}
try {
so.doSomething();
// must catch in order to avoid a compilation error
} catch (SomeOtherExceptionIDontCareAbout e) {
fail ("doSomething failed");
}
assertTrue ("doSomething didn't work", so.isSomethingDone());
}
}
Now consider how much cleaner the code looks without exception handling:
public class SomeTest
SomeObject so;
#Before
public void setUp() {
so = new SomeObject();
}
// Any exception throwm will mean the test did not succeed
#Test
public void TestSomeFlow() throws Exception {
so.init();
so.doSomething();
assertTrue ("doSomething didn't work", so.isSomethingDone());
}
}
Functionally, there is no difference. It only means that the compiler wont complain if you throw a non-RuntimeException. Since JUnit will catch any exception thrown by the test method anyway, it does not really matter.
However, it is usually considered a better practice to catch the Exception yourself and use the fail method of JUnit, in which case you do not need the throws clause.

Categories

Resources