wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

By Date: January 2020

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 on 10 January 2020 | Comments (1) | categories: Java UnitTesting