JUnit4 and exception handeling - java

The following code does not compile, becouse of unreachable catch block.
I want write "tues" function and call it in many other unit test functions.
Is that possible and how to implement that?
private void catchException(boolean condition) {
try
{
assertTrue(condition);
}
catch (SomeException e)
{
fail("exception = " + e.getMessage());
}
}
Thanks!

There is zero need to catch an exception within a test method to fail it:
public Object methodUnderTest() throws SomeException {
...
}
#Test
public void testMethod() throws SomeException() {
Object obj = methodUnderTest();
assert...
}
If SomeException is thrown by methodUnderTest(), testMethod() will fail.

The problem with your code is that assertTrue does not throw SomeException, if you substitute it with the function that does, it will compile.

I'm not entirely sure what you're asking here, but there are a couple things wrong with the code you posted.
You can only have a catch block for a checked exception if the code in the try can potentially throw an exception of the same type you are catching. Since checked exceptions must be declared in the throws clause of a method, you can check to see if any of the methods you are calling throw the exception types you are catching. From the JUnit documentation on assertTrue:
public static void assertTrue(boolean condition)
You can see it doesn't throw any checked exceptions.
Also, calling fail() in a catch block in a JUnit test is not really necessary. A unit test will automatically fail if an uncaught exception is thrown.

Just add throws WhateverException to your test signature and the test will fail if an exception is thrown.

It is actually not really clear what you what to achieve with your code. If you want to have a nicely formatted message in the exception fired by jUnit if your assert fails then consider writing it in this way:
assertTrue("Condition should hold because....", conditionToCheck);
In this way jUnit will print the message you provided if the check fails. I highly recommend this, especially if you have lots of tests because it
helps you to quickly identify the problem
helps your team member to understand the purpose of your assert

Modifying SomeException by Exception will cause the code to compile.

Obviously my question is not clear.
I have many unit tests and all methods are throwing same exception with different error message. "SomeException" is exception I must catch and read error message from it.
What I want to achive is to write one method which will be common to all unit tests and where I could print error message.
Now unit tests looks like this
public void test_something()
{
try
{
assertTrue(bw.doSomething("test"));
}
catch (SomeException e)
{
fail("exception = " + e.getReason());
}
}
public void test_something1()
{
IBroadworks bw = getSomehting1();
try
{
assertTrue(bw.doSomething1("test1"));
}
catch (SomeException e)
{
fail("exception = " + e.getReason());
}
}
...
So below code is repeating in all unit tests and that is not ok.
...
try{
assertTrue(condition);
}
catch (SomeException e)
{
fail("exception = " + e.getReason());
}
...

Related

How to handle an exception in Java thrown by a method into another method?

Let's suppose I have this class:
public class Obj1{
...
public void do_Something(int someParameter) throws SomeException {
if(...) throw new SomeException();
...
}
...
}
then, somewhere
public class Obj2{
...
public void do_SomeOtherThing(Obj1 obj1){
obj1.do_Something();
//apparently the only solution is try-catching it directly, even if I'm not in the main...
...
}
I've learned that exceptions should only be thrown by METHOD, and catched by MAIN, so, my question is: is try-catch the unique way to handle sub-method exceptions, or the most external method (do_SomeOtherThing) will throw it, so that I can try-catch it directly in main, deleting the try-catch in Object2 class?
Basically, can I do as follows?
public static void main(String[] args){
Object1 obj1 = new Object1();
Object2 obj2 = new Object2();
try{
obj2.do_SomeOtherThing(obj1);
}
catch(SomeException e){
...
}
}
or not?
A checked exception is part of the contract that a method has with its caller, and a thrown exception will always need to be handled one way or another.
The correct answer depends on the exact situation:
The caller can handle the exception:
String getStringFromRemoteServer() throws IOException { ... }
String getConfigString() {
try {
return getStringFromRemoteServer();
} catch (IOException e) {
LOG.warn("Failed to contact server, using local version.", e);
return getLocalString();
}
}
In this case we have an alternative source of the data we need, so if the preferred method fails we catch the exception, log it (so that we know a problem exists with our network) and call the alternative.
The exception is fatal, and we don't want any function higher in the call tree to try to handle it.
Configuration parseConfiguration(String configString) throws ParseException { ... }
void loadConfiguration() {
try {
this.globalConfig = parseConfiguration(getConfigString());
} catch (ParseException e) {
throw new RuntimeException("Corrupted config", e);
}
}
In this case an exception means that the configuration of our application is fatally broken. There is no point in trying to handle this error, and no point in any of our callers trying to handle it, so declaring throws on loadConfiguration() would just be confusing clutter. We wrap the exception in a RuntimeException and rethrow it. Note that we don't log it -- there will be some top level reporting of uncaught exceptions, so logging it here would be repetition.
It is still valuable to have parseConfiguration() throw a checked exception, because when we are calling it from the interactive configuration editor we catch the exception and display an error message to the user.
Maybe our caller can handle the exception.
int stringToInteger(String s) throws BadNumberException { ... }
String decimalStringToHexString(String s) throws BadNumberException {
return intToHex(stringToInteger(s));
}
In this case we are not changing the meaning of the exception -- decimalStringToHexString is converting a number from a string, and one possible outcome is that the string is illegal. Our caller needs to be aware of that as a possible outcome, just as callers of stringToInteger() are, so we simply declare the exception and let our caller handle it. Our caller knows the context they are using the number in, so they can decide how to handle the exception.
A couple of rules:
Never completely ignore an exception (OK, maybe InterruptedException). If you write try { ... } catch (Exception e) {} the empty catch clause will make it hard to spot why your code doesn't work.
When you wrap an exception, always include the original exception as the cause.

(Java) Try-catching specific lines of code vs Try-catching the whole function

So I'm working on a little project in Java and I've come down to the main method and I'm unsure how I should handle try-catching exceptions correctly.
Should I be:
Try-catching specific lines of code that I know will probably throw an exception?
Like:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
//rest of code that probably won't throw any exceptions
}
}
OR
Try-catching the whole main method even if some of the code in the try block will not throw an exception? Like:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
// rest of code that probably won't throw any exceptions
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
}
}
One thing to consider is whether or not the code running after the catch block would still be valid if an exception was thrown. For example, consider the following method:
private void readFile()
{
List<String> lines = null;
try
{
lines = Files.readAllLines(Paths.get("/to/my/file.txt"));
}
catch (IOException e)
{
// log exception...
}
for (String line : lines)
{
System.out.println(line);
}
}
If readAllLines throws that IOException, then the code after the catch block will throw a NullPointerException.
There's a bigger question of deciding when to catch vs re-throw an exception. I answer it by asking myself this question:
"Can my method fulfill its contract if this exception is thrown?"
YES: Handle the exception and continue to fulfill the method's contract.
NO: Re-throw the exception (either in throws clause or wrap in a more appropriate exception type).
For example, with this method,
public static List<String> readAllLines(Path path) throws IOException
if the file does not exist, it cannot return a list of the lines of the file, so it throws an IOException.
On the other hand, this method
public static boolean deleteIfExists(Path path) throws IOException
does not throw an exception if the file does not exist (it instead returns the boolean to tell you what happened). One way to think of the contract of this method is, "after this method executes, there will not be a file at path". So in this case, if the file does not exist, the contract is still fulfilled.
That depends - should the non-exceptional code be executed if either exception is raised? This isn't a "best practices" question, this is a "what are your specifications?" question.
Suppose your code looks like this:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
someValue = defaultValue;
}
// Continue, possibly using the default value
In a case like this, you should wrap only the single line. On the other hand, maybe your code looks like this:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.fatal("The universe is crashing! Run for your lives!");
System.exit();
}
// Continue, assuming that parsing succeeded
In that case, it's a stylistic choice. Either approach is valid, though with such an extreme failure as in this example it might be better to simply declare that the method throws something and forget the try/catch entirely. In fact, whatever your handling code is, if the only thing left for your method to do after it is to bail out, you should consider omitting the try/catch and using a throws clause instead.
This third case, however, is objectively wrong:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.info("something strange happened");
// Don't bother the calling code with the exception, it can't handle it.
}
// Continue, assuming that parsing succeeded
In a case like that, the continuation code must go inside the try block.

How to test that a exception is thrown and caught in junit

I need to test the following code:
try{
while((testBean = csvReader.read(TestBean.class,headers,getCellProcessors()))!=null){
System.out.println("no excpetion");
i=5;
}
}catch(SuperCsvException csvExc){
System.out.println("superCSV excpetion");
i=0;
}catch(Exception ex){
System.out.println("excpetion");
i=0;
}
How to test that whether SuperCsvException is thrown and caught.
JUnit 4 supports this
#Test(expected=<YourExpectedException>.class)
public void testExceptionThrown() {
// call the method that throws exception
}
Either the exception is expected or it's not expected. If expected then you need something like this:
try {
doSomething();
fail("No exception thrown");
}
catch (MyException e) {
// expected
}
The "new" JUnit way of expecting exceptions is the way of rules:
public class ThisIsTheTestClass {
#Rule
public ExpectedException exception = ExpectedException.none();
#Test
public void testingSomeBehaviorThatShouldThrowAnException() throws SuperCsvException {
exception.expect(SuperCsvException.class);
// Put your testing effort here (setup, call, assertions, ...).
}
}
Look at some information about rules, if interested further.
JUnit 4 has support for this. You can declare your unit test as:
#Test(expected=SuperCsvException.class)
public void _testSuperCsvException() {
// call to function containing your code
}
My personal experience is always like
boolean caught = false;
try {
runCodeToThrowException();
} catch (MyException e) {
caught = true;
}
assertTrue(caught);
The reason I dislike to have JUnit handle it is I couldn't control exactly where and how this exception is thrown. That might not be good if I am trying to catch anything generic in a big trunk of code, e.g. IllegalArgumentException.
Your testing approach is wrong. You should consider each method or class you are testing as a unit that has a specification, an accessible interface (non private methods and fields) and an implementation. You should test that the unit, when manipulated through its accessible interface, conforms to its specification. You should not test that the unit has a particular implementation. You may use your knowledge of the implementation to guide your selection of test cases, to choose cases that are likely to be incorrectly implemented.
So in your case, the fact that an exception can be thrown is an implementation detail. You would be wise to have a test case that will also cause that exception to be thrown. As your code tries to catch the exception, I guess this is because the specification of your method says that the method should not throw any exceptions if there is a problem with csvReader. So you could have a test case that sets up csvReader to throw an exception. JUnit will fail the test if the method does throw the exception.
Note the difference: that test case does not test that the exception is thrown and caught (an implementation detail); it tests that the method does not throw or propagate an exception in the situation that a call to csvReader.read will throw an exception. The implementation is allowed to satisfy that constraint by catching the exception or by refraining from calling csvReader.read.
If SuperCsvException is subclass of Exception try something like this:
Exception ex=null;
try {
while ((testBean = csvReader.read(TestBean.class, headers, getCellProcessors())) != null) {
System.out.println("no excpetion");
i = 5;
}
} catch (SuperCsvException csvExc) {
System.out.println("superCSV excpetion");
i = 0;
ex=csvExc;
} catch (Exception ex) {
System.out.println("excpetion");
i = 0;
}
Assert.assertNotNull(ex);

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.

Why try/catch around throwable?

In trying to refactor some I code I attempted to throw the exception in the catch clause like so -
try {
....
}
catch(Exception exception){
.....
throw exception
}
However when I attempted to throw the exception on line "throw exception" the compiler complained with a message that I needed to surround my throw clause in a new try/catch like so -
try
{
....
}
catch (Exception exception)
{
.....
try
{
throw exception
}
catch (Exception e2)
{
...
}
}
Why does the compiler require this and what use does it provide ?
Thanks
The exception java.lang.Exception is a checked exception. This means that it must either be declared in the throws clause of the enclosing method or caught and handled withing the method body.
However, what you are doing in your "fixed" version is to catch the exception, rethrow it and then immediately catch it again. That doesn't make much sense.
Without seeing the real code, it is not clear what the real solution should be, but I expect that the problem is in the original try { ... } catch handler:
If possible, you should catch a more specific exception at that point, so that when you rethrow it, it is covered by the method's existing throws list.
Alternatively, you could wrap the exception in an unchecked exception and throw that instead.
As a last resort, you could change the signature of the method to include Exception in the throws list. But that's a really bad idea, because it just pushes the problem off to the caller ... and leaves the developer / reader in the position of not knowing what exceptions to expect.
In Java, there is a distinction between checked and unchecked exceptions. An unchecked exception can essentially be thrown at any place in code and, if it's not caught somewhere, it will propagate up to the entry point of your application and then stop the process (usually with an error message and stack trace). A checked exception is different: The compiler won't let you just let it propagate, you need to either surround any code which might throw a checked exception with try-catch blocks (and "throw exception" is the simplest case if exception is an instance of a checked exception class) or you must mark the method which contains the call to code that might throw a checked exception with a "throws" declaration. If the desired behaviour is to throw an unchecked exception, then you'll need to wrap the exception in a RuntimeException. If the desired behaviour is to keep the exception checked, then you'll need to add a throws declaration to your current method.
In your original code, nothing catches the thrown exception. I would imagine you either have to specify that your function throws an exception or have another try/catch block as the compiler suggests to catch it.
Instead of
public void yourFunction(){
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
try
public void yourFunction() throws Exception{
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
My guess is that your trying to throw an exception sub class that isn't declared by the method as an exception type it can throw.
The following example works
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws Exception{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
However this example will give an error.
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
Note in the second example I'm simply catching Exception not RuntimeException, it won't compile as I throw Exception which is an undeclared throws, even though I do declare RuntimeException.
Yes the exception is a RuntimeException but the compiler doesn't know that.
Just thought of a third working example to show you. This one also works because your throwing the same type as you declare. (note the only change is the catch block)
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (RuntimeException e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
You need to understand the differences between all three of these answers

Categories

Resources