I have a very simple class like this one below:
abstract class Person
{
private $id;
private $createdOn;
// ... More private properties
protected $unfound = array();
The constructor does a foreach on the passed array $data and, using the correct methods, assigns values to properties. If the method doesn't exist, then the key is added to a protected array to keep a trace of it (i called it $unfound, just to be original!).
public function __construct($data)
{
foreach ($data as $field => $value)
{
$method = 'set' . ucfirst($field);
if (method_exists($this, $method))
{
$this->$method($value);
}
else
{
$this->unfound[] = $field;
}
}
}
The list of methods to set the values for properties
public function setId($id) {
$this->id = $id;
}
public function setCreatedOn($createdOn) {
$this->createdOn = $createdOn;
}
And a list of methods to get those assigned values
public function getId() {
return $this->id;
}
public function getCreatedOn() {
return $this->createdOn;
}
} // END of the class
As you can see, the class doesn't do any complicated task: it accepts an array like
array(
'id' => 4,
'createdOn' => '2015-01-07 20:50:00',
'unknownVar' => 'mah'
// ... Other properties to set
);
So the class cycles through the array and use the key to call the correct method to set the value. Nothing complex i think.
More complex is, instead, testing it.
As it is an abstract class, i cannot instantiate it directly, but i have to mock it.
My problem is that i can't pass to constructor the correct parameters to test if the values assignment is correctly done.
I've tried to use something like:
public function testPerson()
{
$abstractClass = '\My\Namespace\Person';
$testData = array(
'id' => 1,
'createdOn' => '2015-01-07 19:52:00',
'unfound' => 'Inexistent method'
);
$methods = array(
'getId',
'setId'
);
$mock = $this->getMockBuilder($abstractClass)
->setConstructorArgs(array($testData))
->setMethods($methods)
->getMockForAbstractClass();
$this->assertEquals($testData['id'], $mock->getId());
}
In testPerson(), the $methods variable doesn't contain all methods i need, but for the testing of the test (please, excuse me for the play with words! :) ) i think they are sufficient.
But PHPUnit tells me that:
Failed asserting that null matches expected 1.
It seems like the constructor isn't called, also if the code coverage tells me that methods are called.
is there anyone who can help me understand what is happening and how can i test this class?
Thank you!