The problem these days its so easy to spin-up resources from within one's test case that I'm not sure that's a fair unit/integration litmus test. Presently, I count libraries like Unitils, DbUnit, and Hypersonic as tools in my testing arsenal. The latter is an in-memory database, and by leveraging it within my test case I eliminate the need to have, for example, MySQL running during test execution.
In many of my tests, I've swapped out use of MySQL with Hypersonic, allowing my test case to be truly autonomous. Using the classic test definition, I've made my test case go from integration to unit test. Merely by changing the spring context file to point to an actual running database, Presto! -- its an integration test again. There's something amiss with the test definition, I feel, when traversing between the two types of test is so easily made.
I'm compelled then to reflect on what unit testing means to me. One of my core beliefs is that unit testing is about isolation -- truly testing only that code which is executed within a class. Take your typical DAO method (excuse the formatting):
public Widget getWidgetByLabel(String label) {
List results = hibernateTemplate.find("select w from Widget w where w.label=?", label);
if(results.isEmpty()) {
throw new WidgetNotFoundException("No widget exists with the label:" + label);
}
return (Widget) results.get(0); // ignoring too many results for now.
}
When I put on my unit-testing peering specks, I see very little logic to test here. This is a happy conclusion -- having too much logic within one's DAO is not a good thing. My unit test for this method would merely insure:
- The proper arguments are passed to the hibernateTemplate.find() method.
- An empty List will trigger an exception.
- A non-empty List will make the method return the first object in the list.
Therefore, I think I'm revising my personal litmus test. Only when a test case is truly testing in isolation will I consider it a unit test. If a test case involves logic in other classes and libraries, I shall regard these as integration tests, even if it requires no outside resources.