Unit Tests and Singletons
Good developers test their code. There are plenty of frameworks and tools around to make it less painful. Not every code is testable, so you write test first, to avoid getting stuck with untestable code. However there are situations where Unit Testing and pattern get into each other's way
The singleton and test isolation
I'm a big fan of design patterns, after all they are a well-proven solutions for specific known problems. E.g. the observer pattern is the foundation of reactive programming.
A common approach to implementing cache is the singleton pattern, that ensures all your code talks to the same cache instance ,independent of what cache you actually use: Aerospike, Redis, Guava, JCS or others.
Your singleton would look like this:
public enum TicketCache {
INSTANCE;
public Set<String> getTickets(final String systemId) {
Set<String> result = new HashSet<>();
// Your cache related code goes here
return result;
}
public TicketCache addTicket(final String systemId, final String ticketId) {
// Your cache/persistence code goes here
return this;
}
}
and a method in a class returning tickets (e.g. in a user object) for a user could look like this:
public Set<String> getUserTickets() {
Set<String> result = new HashSet<>();
Set<String> systemsResponsibleFor = this.getSystems();
systemsResponsibleFor.forEach(systemId ->
result.addAll(TicketCache.INSTANCE.getTickets(systemId)));
return result;
}
Now when you want to test this method, you have a dependency on TicketCache
and can't test the getUserTickets()
method in isolation. You are at the mercy of your cache implementation. But there is a better way
Read more
Posted by Stephan H Wissel on 10 January 2020 | Comments (1) | categories: Java UnitTesting