Xavier Boubert
Xavier Boubert

Reputation: 139

How to mock a class created inside the tested class?

In the PHPUnit documentation, the section dealing with mocks explain how to attach a mock object inside the tested class :

...
$observer = $this->getMockBuilder('Observer')
                 ->setMethods(array('update'))
                 ->getMock();
...
$subject = new Subject('My subject');
$subject->attach($observer);
$subject->doSomething();

In my case, I want to test a Subject method. This method create many objects like this:

public function myMethod() {
    for($i = 0; $i < 10; $i++) {
        $this->collection []= new Observer(/* some data */);
    }
}

How can I mock all of the Observers?

Upvotes: 0

Views: 660

Answers (1)

Schleis
Schleis

Reputation: 43700

You can't mock the class. The new operator will get the definition of the class based on your autoloader or what it is memory already. You can't dynamically replace the class definition in your test.

You could create an alternate class definition for Observer that would have defined behaviors and would in essence be a "mock" class that you would use. The problem with this is that if you run this test with the tests for the actual Observer class, you will end up with an error that you cannot redefine the class. And things get really complicated.

Your example is pretty simplistic but I would verify it by making sure that all the elements in Subject::collection are instances of Observer. If there was any specific data that I knew about each observer then I would use actual Observer methods to verify them. (This isn't a good practice though).

If your method is creating the objects and then calling methods on them, I would seriously reconsider your design. I would break up myMethod into at least two methods. One that attaches an Observer object that you can use in your test to pass a mock object in with. And the other that calls the methods of the Observer which would be the rest of the myMethod function that you don't have.

Upvotes: 1

Related Questions