Java Reference
In-Depth Information
JUnit best practices: test only what can possibly break
You may have noticed that we didn't mock the Account class. The reason is that
this data access object class doesn't need to be mocked—it doesn't depend on
the environment, and it's simple. Our other tests use the Account object, so they
test it indirectly. If it failed to operate correctly, the tests that rely on Account
would fail and alert us to the problem.
7.3
Refactoring with mock objects
Some people used to say that unit tests should be totally transparent to your code
under test, and that you should not change runtime code in order to simplify testing.
This is wrong! Unit tests are first-class users of the runtime code and deserve the same
consideration as any other user. If your code is too inflexible for the tests to use, then
you should correct the code.
For example, what do you think of the following piece of code?
[...]
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
[...]
public class DefaultAccountManager implements AccountManager {
private static final Log LOGGER =
LogFactory.getLog(AccountManager.class);
Create
a Log
public Account findAccountForUser(String userId) {
LOGGER.debug("Getting account for user [" + userId + "]");
ResourceBundle bundle =
PropertyResourceBundle.getBundle("technical");
String sql = bundle.getString("FIND_ACCOUNT_FOR_USER");
// Some code logic to load a user account using JDBC
[...]
}
[...]
}
Retrieve a SQL
command
Does the code look fine to you? We can see two issues, both of which relate to code
flexibility and the ability to resist change. The first problem is that it isn't possible
to decide to use a different Log object, because it's created inside the class. For test-
ing, for example, you probably want to use a Log that does nothing, but you can't.
As a rule, a class like this should be able to use whatever Log it's given.
The goal of this class isn't to create loggers but to perform some JDBC logic. The
same remark applies to the use of PropertyResourceBundle . It may sound okay right
now, but what happens if you decide to use XML to store the configuration? Again, it
shouldn't be the goal of this class to decide what implementation to use.
 
 
 
 
 
 
Search WWH ::




Custom Search