Showing posts with label design principles. Show all posts
Showing posts with label design principles. Show all posts

29 May 2012

Mocking static methods and the Gateway pattern

A year ago I started to use mocking libraries (e.g., Mockito, EasyMock, ...), both for learning something new and for testing purpose in hopeless cases.
Briefly: such a library makes it possible to dynamically redefine the behaviour (return value, thrown exceptions) of the methods of the class under test, in order to run tests in a controlled environment. It makes it possible even to check behavioural expectations for mock objects, in order to test the Class Under Test's interactions with its collaborators.
A few weeks ago a colleague asked me: "[How] can I mock a static method, eventually using a mock library?".
In detail, he was looking for a way to test a class whose code was using a static CustomerLoginFacade.login(String username, String password) method provided by an external API (an authentication custom API by a customer enterprise).
His code looked as follows:

public class ClassUnderTest {
  ...
 public void methodUnderTest(...) {
  ...
   // check authentication
   if(CustomerLoginFacade.login(...)) {
      ...
  } else {
    ...
   }
 }
}

but customer's authentication provider was not accessible from test environment: so the main (but not the only: test isolation, performances, ...) reason to mock the static login method.

A quick search in the magic mocking libraries world revealed that:
  • EasyMock supports static methods mocking using extensions (e.g, Class Extension, PowerMock)
  • JMock doesn't support static method mocking
  • Mockito (my preferred [Java] mocking library at the moment) doesn't support static method mocking, because Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand & change (see official FAQ). The same position appears even in a JMock-related discussion. PowerMock provides a Mockito extension that supports static methods mocking.
So, thanks to my colleague, I will analize the more general question "Ho can I handle external / legacy API (e.g., static methods acting as service facade) for testing purposes?". I can identify three different approaches:
  • mocking by library: we can use a mocking library supporting external / legacy API mocking (e.g, class' mocking, static methods' mocking), as discussed earlier
  • mocking by language: we can refer to the features of a dynamically typed programming language to dynamically change external / legacy API implementation / behaviour. E.g., the login problem discussed earlier can be solved in Groovy style, using the features of a language fully integrated with the Java runtime: 
CustomerLoginFacade.metaClass.'static'.login = {
              return true;
}; 

Such an approach can be successfully used when CustomerLoginFacade.login's client code is Groovy code, not for old Java client code.
  • Architectural approach: mocking by design. This approach refers to a general principle: hide every external (concrete) API behind an interface (i.e.: coding on interfaces, not on concrete implementation). This principle is commonly knows as dependency inversion principle.
So, we can solve my colleague's problem this way: first, we define a login interface:

public interface MyLoginService {
 public abstract boolean login(final String username, final String password);
}

Then, we refactor the original methodUnderTest code to use the interface:

public class ClassUnderTest {
  private MyLoginService loginService;
 // Collaborator provided by Constructor injection (see here for
 //  a discussion about injection styles)
 public ClassUnderTest(final LoginService loginService) {
  this.loginService = loginService;
 }   
 ...
 public void methodUnderTest(...) {
  ...
   // check authentication
   if(loginService.login(...)) {
      ...
  } else {
    ...
   }
 }
}


So, for testing pourposes, we can simply inject a fake implementation of the MyLoginService interface:

public void myTest() {
 final ClassUnderTest cut = new ClassUnderTest(new FakeLoginService());
 cut.methodUnderTest(..., ...);
 ...
}


where FakeLoginService is simply
 
public class FakeLoginService implements MyLoginService {
 public boolean login(final String username, final String password) {
  return true;
 }
}

and the real, pruduction implementation of the interface looks simply like this:

public class RealLoginService implements MyLoginService {
 public boolean login(final String username, final String password) {
  return CustomerLoginFacade.login(username, password);
 }
}


Ultimately, the interface defines an abstract gateway to the external authentication API: changing the gateway implementation, we can set up a testing environment fully decoupled from real customer' authentication provider
.
IMHO, i prefer the last mocking approach: it's more object oriented, and after all... my colleague called me once the more OO person I know :-). I find this approach more clean and elegant: it's built only upon common features of programming languages and doesn't refer to external libraries nor testing-oriented dynamic languafe features.
In terms of design, too, I think it's a more readable and more reusable solution to the problem, which allows a clearer identification of responsibilities of the various pieces of code: MyLoginService defines an interface, and every implementation represents a way to implement it (a real-life (i.e.: production) implementation versus the fake one).

However, method mocking (by library or by language, doesn't matter) is in certain, specific situations a very useful technique, too, especially when code that suffers static dependencies (ClassUnderTest in our example) is an example of legacy code, designed with no testing in mind, and is eventually out of developer control.
[Incidentally: the solution adopted by my colleague was just that I have proposed (i.e., mocking by design)]

Credits: thanks to Samuele for giving me cause to analyze such a problem (and for our frequent and ever interesting design-related discussion). Thanks to my wife for hers valuable support in writing in pseudo-English

11 February 2012

Singleton, testing and dependency inversion

Singleton: pattern or antipattern?
Accordingly to Wikipedia, Singleton is a creational pattern, used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. So, it's a pattern!
But it's an antipattern, too, especially from the point of view of testing: it's a (simple) variant of Service Locator testability antipattern.

As states Jens Schauder in his post Fixing the Singleton, there are two key characteristic of the (classic implementation of) singleton:
  • There can be only a single instance of the class developed as singleton
  • There is a central, global acces point to the singleton instance
Alhough the first one is the main - if not the only - reason for use of Singleton pattern, it comes almost alway with the second one. But... while the first one is a conceptual featur of the pattern, the second is nothing but an implementation detail!

We can therefore speak of conceptual Singleton, when we have a class that can be instantiated only once in the application lifecycle, and syntactic Singleton, with reference to the traditional GoF's implementation. 
Well, my idea is that you can think of two different basic implementation strategies for conceptual Singletons:
  • Singleton by syntax - traditional GoF's implementation, through private static instance and public static (and then: global) accessor
  • Singleton by contract / application - implementation of the concept of "single class instance" without syntactic constraints: application code takes care of respect the contract of "single instance". Tipically, application infrastructure responsible for creating object and setting up collaborators references instantiates the Singleton class only once and passes created instance to modules interested in its use: this is substantially an application of Dependency Inversion Principle, and can be implemented through Inversion of Control frameworks like Spring and Google-Guice (for a good discussion about self implemented dependency injection, see this article).
First approach suffers the problem suggested initially: there is a global state, publicly accessible, liberally referenced everywhere in the client code - and global state is evil!
The second one, instead, provides a conceptual Singleton instance without referring to syntactical constraints: application lifecycle infrastructure ensures unicity of the Singleton class instance.

In code:
  • Singleton by syntax:
    package singleton;

    public class UIDGenerator {
      private static final UIDGenerator INSTANCE = new UIDGenerator();

      public static UIDGenerator getInstance() {
        return INSTANCE;

      }

      private UIDGenerator() {
      }

      public String nextId() {
        return ...;
      }
    }

    Client code:

    public void foo() {
      String newId = UIDGenerator.getInstance().nextId();
      // Use newId
    }
      
    public void bar() {
      Account account = new Account(UIDGenerator.getInstance().nextId());
      // Use newly created Account
    }
    This the classical GoF's implementation of pattern Singleton: private constructor and final static INSTANCE ensure instance unicity, public static accessor provides global access to singleton instance.
  • Singleton by contract:
    package singleton;

    public interface UIDProvider {
      public abstract String nextUid();
    }


    Client code:

    package singleton;

    public class AccountManager {
      private final UIDProvider uidProvider;

      public AccountManager(UIDProvider uidProvider) {
        this.uidProvider = uidProvider;
      }
      
      public void bar() {
        Account account = new Account(uidProvider.nextUid());
        // Use newly created Account
      }
    }
In the second implementation we define an interface for UID generation: application infrastructure (i.e.. in most cases. an Inversion of Control container, like Spring) will ensure that a single instance of a class implementing UIDProvider is passed whenever it's necessary.
This way we can obtain the conceptual part of the pattern without the syntactical one: there is no public static context accessed everywhere, and a reference to the singleton is indeed injected into modules that need it. So, unlike in the first case, it's possibile to mock UIDProvider for testing purposes (for example because real implementation is time expensive, or there is a fee for every use, or simply because unit testing is isolation testing and we need to make assumptions on generated uid in testing code):

public class AccountManagerTest {
  @Test
  public void testMethod() {
    AccountManager underTest = new AccountManager(new FixedUIDProvider());
    // Exercises underTest
  }
}


This is IMHO a more, more (more!) powerful approach for implementing singleton than the classic one: can you figure out how to mock UIDGenerator.getInstance().nextId() calls?
The basic idea behind this proposal is a variation of single responsibility principle: classic singleton implementation drives to classes that implement two responsibilities: a functional responsibility - what the class do - and a structural responibility - how is the class instantiated and the instance accessed. Inversion of Control containers, and more generally the idea of Dependency Inversion, support separation of responsibilities by divide functional code and object graph lifecycle management code: this leads to clearer, simpler design, that decouples singleton implementations from client modules and supports testing in a more effective way.