title: unit test a method that creates an object
body: <p>I'm trying to get my head round <strong>Unit Testing</strong> and there's one more piece of the jigsaw I need to find.</p>
  
  <p>What I'm trying to do is write tests for the following code. In this case, I've got a really simple Front Controller (written in PHP).</p>
  
  <pre><code>class frontController
  {
     public function routeRequest($oRequest)
     {
        $sClassname = $oRequest-&gt;getController();
        $sMethod = $oRequest-&gt;getAction();
  
        $oController = new $sClassname();
  
        $oResponse = $oController-&gt;{$sMethod}($oRequest);
  
        return $oResponse;
     }
  
  }
  </code></pre>
  
  <p>The problem I have is because the code <em>creates new objects</em>. I can easily <strong>mock</strong> the request object so that I can tightly control what it will actually do within my test case. I'm not sure the best way to actually replace the <em>controller</em> with a test double.</p>
  
  <p><a href="http://www.ibm.com/developerworks/library/j-mocktest.html" rel="nofollow noreferrer">This article from IBM</a> suggests having a factory method for creating my controller and then overriding this with a <em>specific</em> class used for testing:</p>
  
  <pre><code>class frontController
  {
     public function routeRequest($oRequest)
     {
        $sMethod = $oRequest-&gt;getAction();
  
        $oController = $this-&gt;createController($oRequest);
        $oResponse = $oController-&gt;{$sMethod}($oRequest);
  
        return $oResponse;
     }
  
     protected function createController($oRequest)
     {
        $sClassname = $oRequest-&gt;getController();
        return new $sClassname();
     }
  
  }
  </code></pre>
  
  <p>and then for testing perhaps something like this:</p>
  
  <pre><code>class testFrontController extends frontController
  {
     public function setMockController($oMockController)
     {
        $this-&gt;oMc = $oMockController;
     }
  
     protected function createController($oRequest)
     {
        return $this-&gt;oMockController;
     }
  }
  </code></pre>
  
  <p>(note this isn't quite what the article says, but I'm thinking it would be most useful to me if it did this)</p>
  
  <p>Another solution could be to have another class that creates the controller. This would then be a dependent class of the frontController. This way I can replace the factory/creation class during testing with a test double. Something like this:</p>
  
  <pre><code>class frontController
  {
     public function routeRequest($oRequest, $oControllerFactory)
     {
        $sMethod = $oRequest-&gt;getAction();
  
        $oController = $oControllerFactory-&gt;create($oRequest);
        $oResponse = $oController-&gt;{$sMethod}($oRequest);
  
        return $oResponse;
     }
  }
  
  class controllerFactory
  {
     public function create($oRequest)
     {
        $sClassname = $oRequest-&gt;getController();
        return new $sClassname();
     }
  }
  </code></pre>
  
  <p>I guess the dependency injection could be taken care of in the front controller constructor or via a setter instead of a parameter to the actual "route" method.</p>
  
  <p>I think I prefer option 2.</p>
  
  <p><strong>Is either of these two methods the right way of going about testing this kind of thing?</strong></p>
  
  <p><em>(perhaps "good way" would be better word here!)</em></p>
  
  <p>Any thoughts or suggestions on option 1 vs option 2 appreciated or indeed any alternatives. Remember - the key thing is about how to <strong>test an object that itself creates other objects</strong> as part of its execution.</p>
  
  <p>Thanks!</p>