views:

77

answers:

2

Is there any way to set a class level variable within a mock object?

I have the mock object set similar to this:

$stub = $this->getMock('SokmeClass', array('method'));
$stub->expects($this->once())
         ->method('method')
         ->with($this->equalTo($arg1));

Win the real class there is a variable that needs to be set for it to work properly. How can I set that variable within a mock object?

A: 

The idea of a stub is to replace a dependency with a test double offering the same method interface that (optionally) returns configured return values. This way, the SUT can work with the double like it was the dependency. If you need a specific return value from the stub, you just tell it what it should return, e.g.:

// Create a stub for the SomeClass class.
$stub = $this->getMock('SomeClass');

// Configure the stub.
$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->returnArgument(0));

$stub->doSomething('foo'); // returns foo

See http://www.phpunit.de/manual/current/en/test-doubles.html

Gordon
I guess I should have made the example easier to understand. The class is something similar to this:class SomeClass{ $someVar; public function setSomeVar(Color $blue){ $someVar = "Blue"; } public function getSomeVar(){ return $someVar; }}In the Mock Object, I cant set the variable, so when I use it anywhere else in the object I get a null...
Enrique
@Enrique Hmm, either your or me is not getting it :) You can tell the Mock what it should return when you create it. There is no need to set anything inside it. If you want it to return blue, tell it to return blue.
Gordon
@Gordon OK. Maybe I'm missing something. Let me try to explain teh situation I'm in without spilling too many beans. I have a method 'queue' which sends data over to a table. for 'queue' to run a class level variable $transport has to be set or else it throws an error (for not knowing where to go). I need to set $transport to something other than null and the setter doesnt return an argument (there is no getter for the 'queue' method to call. its old legacy code...)
Enrique
@Enrique Ok, but how will the queue be invoked? If it throws an error I supposed you somehow trigger the transport. That's what you would mock then. It's somewhat difficult to understand this without seeing any actual code. Maybe any of http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html will help?
Gordon
@Gordon Thank you for all your help buddy. Here is an example of the code (objects renamed and core functionality ripped for IP reasons, but the idea for what I need the mock object to do is there)... http://pastebin.com/YP0FAspB . That is the class I am trying to mock, and without the class variable set, the whole mock object wont work...Hope this help buddy. :)
Enrique
@Enrique I still might not be getting it, but if MyClass is the class you want to mock (not test), then stub the `sendObject()` method. If that's not possible for whatever reason, try to mock `$StaticClass` inside it (see the articles I linked earlier). MyClass seems to be just a wrapper for it anyway. I'm sorry I cant give you a definite solution to this. You might want to consider refactoring MyClass or whatever is inside `$StaticClass` into something more testable though.
Gordon
A: 

Don't know why this works but it seems to for me. If you put the __get magic method as one of the overridden methods e.g.

$mock = $this->getMock('Mail', array('__get'));

You can then you can successfully do

$mock->transport = 'smtp';
Nat