Reputation: 353
I have got a problem with TDD and impossible exceptions.
Let's say we have got a class named Foo (example):
Class Foo {
public String getString(boolean shouldThrow) throws Exception {
if(shouldThrow) throw new Exception();
return "nonsense";
}
}
Foo throws an exception only under certain circumstances (for simplicity i take a boolean here).
Now i want to create a class named Bar which reverses the string of Foo without throwing an exception.
Test:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
assertEquals("esnesnon", bar.getReversedString());
}
}
I know that the boolean is false all the time. So the method getReversedString() will never throw an exception. But since it throws no exception, I can't write an assert which leads me to write the try/catch block inside of Bar.
So the Test will look like this:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
try {
assertEquals("esnesnon", bar.getReversedString());
} catch (Exception e) {
// ... will never happen
}
}
}
But that is bad, because the exception will never happen and I have to write the try/catch-block every time I use the getReversedString() method. So I want the class like this:
class Bar {
public String getReversedString() {
Foo foo = new Foo();
try {
String s = foo.getString(false);
} catch (Exception e) {
// will never happen...
}
// ... reverse string ...
return reversedString;
}
}
But since the exception will never happen, I can't write a test for that try/catch-block - so I can't write the try/catch-block inside of Bar because TDD says "only write code if the lights are red".
It is a doom loop...
I hope you got me! Thanks!!
Upvotes: 0
Views: 481
Reputation: 121710
Make the test itself throw the exception:
public void testShouldReturnReversedStringOfBar()
throws Exception
{
Bar bar = new Bar();
assertEquals("esnesnon", bar.getReversedString());
}
If an exception is thrown then the test will be marked as an error; which is "a failure but not as we know it, Jim" -- that fails anyway.
and by the way, throwing Exception
is bad practice; when you catch Exception
you also get to catch all RuntimeException
s, that is, all unchecked exceptions as well. Don't do that.
Upvotes: 4
Reputation: 579
You could either add a throws declaration to the test method as fge already suggested, or you could consider re-designing your code by splitting your if into two separate methods (one that throws exception and one that doesn't)
class Foo {
public String getStringWithException() throws Exception {
// return data or throw exception if something goes wrong
}
public String getStringWithoutException() {
// return data
}
}
Upvotes: 0
Reputation: 14217
The TDD
is a way to help you verify your program can work correctly. Though the Exception
will never occur. I think you can throw Exception
in junit
test method. Just like:
public void testShouldReturnReversedStringOfBar() throw Exception{
....
}
Upvotes: 0