Reputation: 139
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
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