Java Reference
In-Depth Information
protect us from introducing errors in our code. To do this we need to test every condi-
tion under which our application might be executed. We start investigating the excep-
tional conditions in the next chapter.
3.3
Testing exception handling
So far, your tests have followed the main path of execution. If the behavior of one
of your objects under test changes in an unexpected way, this type of test points to
the root of the problem. In essence, you've been writing diagnostic tests that moni-
tor the application's health.
But sometimes bad things happen to good programs. Say an application needs to
connect to a database. Your diagnostics may test whether you're following the data-
base's API . If you open a connection but don't close it, a diagnostic can note that
you've failed to meet the expectation that all connections must be closed after use.
But what if a connection isn't available? Maybe the connection pool is empty. Or
perhaps the database server is down. If the database server is configured properly and
you have all the resources you need, this may never happen.
All resources are finite, and someday, instead of a connection, you may be handed
an exception. “Anything that can go wrong will.”
If you're testing an application by hand, one way to test for this sort of thing is to
turn off the database while the application is running. Forcing error conditions is an
excellent way to test your disaster-recovery capability. Creating error conditions is also
time consuming. Most of us can't afford to do this several times a day—or even once a
day. In addition, many other error conditions aren't easy to create by hand.
Testing the main path of execution is a good thing—and a requirement. Testing
exception handling is just as important and should also be included as a requirement.
If the main path doesn't work, your application won't work either (a condition you're
likely to notice.)
JUnit best practices: test anything that could possibly fail
Unit tests help ensure that your methods are keeping their API contracts with other
methods. If the contract is based solely on other components' keeping their con-
tracts, then there may not be any useful behavior for you to test. But if the method
changes the parameter's or field's value in any way, then you're providing unique
behavior that you should test. The method is no longer a simple go-between—it's
a method with its own behavior that future changes could conceivably break. If a
method is changed such that it isn't simple anymore, then you should add a test
when that change takes place but not before.
As the JUnit FAQ puts it, “The general philosophy is this: if it can't break on its
own , it's too simple to break.” This is also in keeping with the Extreme Program-
ming rule: “No functionality is added early.”
 
 
 
 
 
 
 
 
 
Search WWH ::




Custom Search