title: How to mock an Object Factory
body: <p>I use Factories (see <a href="http://www.php.net/manual/en/language.oop5.patterns.php" rel="nofollow">http://www.php.net/manual/en/language.oop5.patterns.php</a> for the pattern) a lot to increase the testability of our code. A simple factory could look like this:</p>
  
  <pre><code>class Factory
  {
      public function getInstanceFor($type)
      {
          switch ($type) {
              case 'foo':
                  return new Foo();
              case 'bar':
                  return new Bar();
          }
      }
  }
  </code></pre>
  
  <p>Here is a sample class using that factory:</p>
  
  <pre><code>class Sample
  {
      protected $_factory;
  
      public function __construct(Factory $factory)
      {
          $this-&gt;_factory = $factory;
      }
  
      public function doSomething()
      {
          $foo = $this-&gt;_factory-&gt;getInstanceFor('foo');
          $bar = $this-&gt;_factory-&gt;getInstanceFor('bar');
          /* more stuff done here */
          /* ... */
      }
  }
  </code></pre>
  
  <p>Now for proper unit testing I need to mock the object that will return stubs for the classes, and that is where I got stuck. I thought it would be possible to do it like this:  </p>
  
  <pre><code>class SampleTest extends PHPUnit_Framework_TestCase
  {
      public function testAClassUsingObjectFactory()
      {
          $fooStub = $this-&gt;getMock('Foo');
          $barStub = $this-&gt;getMock('Bar');
  
          $factoryMock = $this-&gt;getMock('Factory');
  
          $factoryMock-&gt;expects($this-&gt;any())
              -&gt;method('getInstanceFor')
              -&gt;with('foo')
              -&gt;will($this-&gt;returnValue($fooStub));
  
          $factoryMock-&gt;expects($this-&gt;any())
              -&gt;method('getInstanceFor')
              -&gt;with('bar')
              -&gt;will($this-&gt;returnValue($barStub));
      }
  }
  </code></pre>
  
  <p>But when I run the test, this is what I get:</p>
  
  <pre><code>F
  
  Time: 0 seconds, Memory: 5.25Mb
  
  There was 1 failure:
  
  1) SampleTest::testDoSomething
  Failed asserting that two strings are equal.
  --- Expected
  +++ Actual
  @@ @@
  -bar
  +foo
  
  FAILURES!
  Tests: 1, Assertions: 0, Failures: 1.
  </code></pre>
  
  <p>So obviously it is not possible to let a mock object return different values depending on the passed method arguments this way. </p>
  
  <p>How can this be done?</p>