Reputation: 757
I've been trying to decouple my dependencies so that I can unit test functions within a class but I ran into a problem where I have a function that loops through an array of data and creates new objects based on the data. The new object does a myself INSERT
with the data.
How could I write this function so I can mock the objects to creates in the loop?
public function createObjects($array_of_data)
{
$new_objects = [];
foreach($array_of_data as $data)
{
//do some stuff with the data
$new_object = new newObject($data);
$new_object->saveToDB();
$new_objects[] = $new_object;
}
return $new_objects;
}
Upvotes: 1
Views: 296
Reputation: 1482
I would suggest creating a new factory class, injecting that class into the createObjects()
method (or via that class's constructor, or via a setter method), then mocking that factory when it comes time to test createObjects()
.
Here's a quick example. Be sure to note the FactoryInterface
typehint in the YourClass::createObjects()
method, which makes all of this possible:
interface FactoryInterface
{
public function createObject($data);
}
class ObjectFactory implements FactoryInterface
{
public function createObject($data)
{
return new newObject($data);
}
}
class YourClass
{
public function createObjects($array_of_data, FactoryInterface $objectFactory)
{
$new_objects = [];
foreach ($array_of_data as $data) {
$new_objects[] = $objectFactory->createObject($data);
}
return $new_objects;
}
}
class MockObjectFactory implements FactoryInterface
{
public function createObject($data)
{
// Here, you can return a mocked newObject rather than an actual newObject
}
}
class YourClassTest extends PHPUnit_Framework_TestCase
{
public function testCreateObjects()
{
$classUnderTest = new YourClass();
$new_objects = $classUnderTest->createObjects(
[1, 2, 3], // Your object initialization data.
new MockObjectFactory()
);
// Perform assertions on $new_objects
}
}
Upvotes: 1