Wednesday, December 25, 2013

Implementing a test stub pattern

First thing first, I don’t create this pattern. I got this idea when I was reading the unit testing strategy from this blog. I like this test pattern because the codes were so clean and very object oriented style. (Before this my unit test code were very messy just like spaghetti). This way, I can easily isolate my mock code into a standalone stub class without messing up with real method.

Before I start using this pattern, let’s see how this pattern could fit into my project. I pick reporting template module for this experiment, which is my favourite module because this module is like a Sergeant who able to tackle different type of reporting problem. The UML diagram below shows the real design on the report template module.

In order to utilize its reporting service, one must inherit HibernateReportService because this class was declare as abstract, and it is the only interface that has contact to the outside world, and all the initialization work are done through the constructor. The query method is the only entry point that could allow customizes query selection in order to complete the reporting job. Code snippet below shows its use:
public class MyReportService extends HibernateReportService<Object> {

    public MyReportService(...) {
        ...
    }

    protected void query() {
        ...
    }

}
There would be a difference when come to initializing the report template unit testing work. As according to the design, I don’t inherit HibernateReportServiceStubber from HibernateReportService, whereas I make a generic template of HibernateReportService type. This idea was great as it allow me to isolate the mock code or fake implementation without messing up with the real implementation in HibernateReportService. Code snippet below showing the primary piece that makes up this stub class:
public class HibernateReportServiceStubber<T extends HibernateReportService<Object>> {

 private T daoReportService;

 public HibernateReportServiceStubber(T daoService) throws Exception {
  
  // capture the DAO that going to be test
  this.daoReportService = PowerMockito.spy(daoService);
 }
 
 public T getReportService() {
  return this.daoReportService;
 }

 // more mock method down the road
} 
Here come to the unit test guy. TheReportingServiceTest is the guy that takes up responsibility to execute the test. Again this guy doesn’t inherit from HibernateReportServiceStubber but he instantiate it and execute the fake implementation provided from the stub class. Below is the sample of his hard work:
public class TheReportingServiceTest {

 private HibernateReportServiceStubber<MyReportService> reportServiceStubber;
 
 @Before
 public void setUp() throws Exception {
  reportServiceStubber = getHibernateReportService();
 }

 private HibernateReportServiceStubber<MyReportService> getHibernateReportService() throws Exception {
  return new HibernateReportServiceStubber<MyReportService>(new MyReportService (...));
 }

 @Test
 public void test(){
  reportServiceStubber.mockCodeA();
  reportServiceStubber.mockCodeB();

  ...
 }

} 
At the end of this experiment, I feel that I'm actually running a behavioural test more than running unit testing on each single detail function/method.

No comments: