Reputation: 1435
I use PHPUnit for my unit tests (Symfony2 app).
This is my method that I want test (simplified):
public function __construct(Email $email)
{
$this->email = $email;
}
public function sendEmail()
{
// Here, more logic and condition, it's simplified
if ($this->email->getOk() === 1) {
$this->email->setSendEmail(1);
}
return $this->email;
}
And my test:
$emailMock = $this->getMock(Email::class);
$emailMock->method('getOk')->will($this->returnValue(1));
$emailMock->method('setSendEmail')->will($this->returnArgument(0));
$email = new Email($emailMock);
$emailModified = $email->sendEmail();
var_dump($emailModified->getSendEmail()); // Returns NULL
My class Email is a Doctrine Entity (the setter and getter is inside) (an example of entity)
How can I test if my mock is hydrated by my class? I want to know if my method works by looking if my object is hydrated.
Edit
I try an other method :
$object = $this->getMock(MyClass::class);
$object->method('setPosition')->will(
$this->returnCallback(
$pos = function ($arg) {
return $arg;
}
)
);
$object->method('getPosition')->will($this->returnValue($pos));
$method = new \ReflectionMethod(MyClass::class, 'testMethod');
$method->setAccessible(true);
$res = $method->invoke(new MyClass($object));
var_dump($res->getPosition()) // Return inexploitable Closure
I would like that $object->getPosition()
return 1
when I execute $object->setPosition(1)
from my external class MyClass() that I test.
Upvotes: 3
Views: 3065
Reputation: 991
Even later, and just a modification of what Matt did above:
$storage = null;
$mock = $this->createMock(MyClass::class);
$mock->expects($this->any())->method('set')->willReturnCallback(
function ($arg) use ($mock, &$storage) {
$storage = $arg;
return $mock;
}
);
$mock->expects($this->any())->method('get')->willReturnCallback(
function () use (&$storage) {
return $storage;
}
);
This allows to store the values "locally" within the test, and doesn't expect you to have visibility to the object properties.
$storage
is sent in as a reference to edit the contents of the variable in the tests scope, not just callback's scope.
Upvotes: 0
Reputation: 1590
Late answer, but I ended up mocking getter
and setter
to be functional like such
// Mock setter
$exceptionEvent->expects($this->once())->method('setResponse')->willReturnCallback(
function($arg) use ($exceptionEvent) {
$exceptionEvent->response = $arg;
}
);
// Mock getter
$exceptionEvent->expects($this->once())->method('getResponse')->willReturnCallback(
function() use ($exceptionEvent) {
return $exceptionEvent->response;
}
);
The class I am testing takes $exceptionEvent
and calls setResponse()
on it. This solution works for me, I then make assertions against $exceptionEvent->getResponse()
after I run it through said class.
Upvotes: 2