Nowadays we are pretty used to instruct our powerful IDE to generate lots and lots of boilerplate with just a couple keystrokes. This is specially the case for Java and, as a consequence, we become as blind to generated code as we used to be blind to banners (until we discovered AdBlock).
Before and after AdBlock (via Lancelhoff)
It is most likely that the junit test template generated by your IDE will look like the following snippet.
Just for today, let’s focus on the generated code. Notice the throws
Exception
part and think why it is there before continuing reading.
That declaration is not there to save you from typing another fancy keystroke
to add a throws clause, which is not so helpful anyway. The throws
declaration is part of a good practice that helps your test cases to be more
independent of each other.
Consider the example sketched in the snippet: you have a class collecting some sort of statistic about a collection of elements. After some TDD, you have the following tests:
Notice that the special value NaN
is expected in the case of an anomalous
input. We might want to throw a checked exception instead of just a NaN
, and
nothing stops us from doing so without modifying other tests thanks to the
throws
declarations.
Without that throws Exception
, this change could cascade not only to the
other cases in this test but to many other test classes in what is called
shotgun surgery. The need to modify several tests when making a single
conceptual change is a signal of poor quality tests that are not independent
enough. You can thank your IDE for this one.
For the production code, this change might be costly as you need to modify all the signatures between this function and the code handling the exception. As Michael Feathers points it out in a classic book1, checked exceptions are not worthy for the general case because they violate the OCP principle.