title: Java. Mock data access object
body: <p>I've encountered problem with mocking data access logic.</p>
  
  <p>I'm developing web application using JavaEE, Struts and my custom data access logic. In this application Struts Action operates with UserDao to retrieve User objects. Lifecycle of the UserDao object is tied to the JDBC transaction. Idea is that when Action creates UserDao object it starts JDBC transaction (necessary JDBC stuff is stored inside UserDao object), all invocations of UserDao methods operate in single JDBC transaction and then Action terminates UserDao object finishing transaction (with either commit or rollback).</p>
  
  <p>The problem is that during tests of the Actions i need to mock this UserDao to make it return User objects with necessary test data.</p>
  
  <p>The only solution i found so far is horrible. I've made following: splitted UserDao into UserDao interface and UseDaoImpl class that implements it. This interface will also be implemented by UserDaoMock that will be returning necessary test data. Next i need some fabric that will return real UserDao (UserDaoImpl) in production run and mock (UserDaoMock) in test run. This fabric should not depend from UserDaoMock type to make production code of the application independent from mock .class file. This results into horrible design.</p>
  
  <p>Shortcomings:</p>
  
  <p>In fabric:</p>
  
  <ul>
  <li><p>I need an instance of UserDao inside fabric just to be able to call <code>instantiate</code> method (which is in fact copy constructor, but i need it to be a method to be able to use polymorphism to choose between UserDaoImpl or UserDaoMock) to create another object of UserDao that will be associated with transaction (depending on runtime type it will be <code>instantiate</code> method of either UserDaoImpl or UserDaoMock).</p>
  
  <p>public class UserDaoFabric {</p>
  
  <pre><code>private static UserDaoFabric instance;
  private UserDao exampleUserDao;
  
  public static UserDaoFabric getInstance() {
      if(instance == null) {
          instance = new UserDaoFabric();
          // By default we initialize fabric with example of real UserDao.
          // In test will be set to example of UserDaoMock with setExampleUserDao method.
          instance.setExampleUserDao(new UserDaoImpl(true));
      }
      return instance;
  }
  
  public UserDao getUserDao() {
      return exampleUserDao.instantiate(true);
  }
  
  public void setExampleUserDao(UserDao userDao) {
      this.exampleUserDao = userDao;
  }
  </code></pre>
  
  <p>}</p></li>
  </ul>
  
  <p>In UserDao:</p>
  
  <ul>
  <li>I need both <code>instantiate</code> method (which in fact is copy constructor).</li>
  <li>Despite that i also need public constructor to initialize fabric with example.</li>
  <li><p>Constructor should have parameter that tells whether it is example or not (whether to start transaction or not).</p>
  
  <pre><code>public final class UserDaoImpl implements UserDao {
  
      private DataSource ds;
      private Connection conn;
  
      public UserDao instantiate(boolean startTransaction) {
          if(startTransaction) {
              return new UserDaoImpl(true);
          } else {
              return new UserDaoImpl(false);
          }
      }
  
      public UserDaoImpl(boolean initiate) {
          if(initiate) {
              // DB connection initialization and start of the transaction
          } else {
              new UserDaoImpl();
          }
      }
  
      private UserDaoImpl() {
      }
  
      @Override
      public void terminate(boolean commit) {
          // End of the transaction and DB connection termination
      }
  
      // Other interface methods implementation ommited
  
  }
  </code></pre></li>
  </ul>
  
  <p>Is there a way to make proper design for testability in this case?</p>
  
  <p>Or, if not, maybe the cause of the problem is that i decided to tie UserDao lifecycle to JDBC transaction? What is possible alternatives? To make UserDao singleton? Won't this be an application bottleneck if all DB interaction will be done via single object.</p>
  
  <p>Or, can you suggest another data access pattern that is more easy to mock?</p>
  
  <p>Please, help. It is the most horrible design i did in my life.</p>
  
  <p>Thanks in advance.</p>