Ethan22
Ethan22

Reputation: 757

How does one unit test function that creates objects in loop?

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

Answers (1)

Nate
Nate

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

Related Questions