How I’m stuck with writing a test for the following code. I want to mock the $userModel but how can I add this to the test?
class PC_Validate_UserEmailDoesNotExist extends Zend_Validate_Abstract
{
public function isValid($email, $context = NULL)
{
$userModel = new Application_Model_User();
$user = $userModel->findByEmailReseller($email, $context['reseller']);
if ($user == NULL) {
return TRUE;
} else {
return FALSE;
}
}
}
Update: the Solution
I did change my class to the following to get it testable, it now uses dependency injection. More information about dependency injection you van find out here
I now call the class like this:
new PC_Validate_UserEmailDoesNotExist(new Application_Model_User()
The refactored class
class PC_Validate_UserEmailDoesNotExist extends Zend_Validate_Abstract
{
protected $_userModel;
public function __construct($model)
{
$this->_userModel = $model;
}
public function isValid($email, $context = NULL)
{
if ($this->_userModel->findByEmailReseller($email, $context['reseller']) == NULL) {
return TRUE;
} else {
return FALSE;
}
}
}
The unit test
class PC_Validate_UserEmailDoesNotExistTest extends BaseControllerTestCase
{
protected $_userModelMock;
public function setUp()
{
parent::setUp();
$this->_userModelMock = $this->getMock('Application_Model_User', array('findByEmailReseller'));
}
public function testIsValid()
{
$this->_userModelMock->expects($this->once())
->method('findByEmailReseller')
->will($this->returnValue(NULL));
$validate = new PC_Validate_UserEmailDoesNotExist($this->_userModelMock);
$this->assertTrue(
$validate->isValid('jef@test.com', NULL),
'The email shouldn\'t exist'
);
}
public function testIsNotValid()
{
$userStub = new \Entities\User();
$this->_userModelMock->expects($this->once())
->method('findByEmailReseller')
->will($this->returnValue($userStub));
$validate = new PC_Validate_UserEmailDoesNotExist($this->_userModelMock);
$this->assertFalse(
$validate->isValid('jef@test.com', NULL),
'The email should exist'
);
}
}
Short answer: you cant, because you hardcoded the dependency into the method.
There is three workarounds for this:
1) Make the used classname configurable, so you can do something like:
or 2) Add a third param to the method signature that allows passing in the dependency
or 3) use
set_new_overload()as described in