Factory Muffin allows us to create objects easily, and consistently when writing tests. These objects will automatically be populated with the data types we specify.
Factory Muffin uses a popular library called Faker to generate random data such as strings, email addresses, phone numbers, credit card numbers and more.
Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you.
There are hundreds of Faker Formatters. These are used to return the random data needed to populate the Factory object. Some examples are:
->catchPhrase; // Monitored regional contingency ->tld; // .com ->ipv4; // 109.133.32.252 ->userAgent; // Mozilla/5.0 (Windows CE) AppleWebKit/5350 (KHTML, like Gecko) Chrome/13.0.888.0 Safari/5350 ->imageUrl(640, 480); // http://lorempixel.com/640/480/ ->titleMale; // Mr. ->creditCardDetails; // array('MasterCard', '4485480221084675', 'Aleksander Nowak', '04/13') ->hexcolor; // #fa3cc2 ->mimeType; // video/x-msvideo ->uuid; // 7e57d004-2b97-0e7a-b45f-5387367791cd
You can find a list of them all by looking at the Faker documentation.
Before we can use Factory Muffin in our tests, we need to define the data we want to be generated. To do this, we create "factories" in the following way:
FactoryMuffin::define( 'User', array( 'username' => 'string', 'password' => 'string', 'email' => 'email', 'address' => 'streetAddress', ) );
These files are generally placed in the root of your "tests" directory. For example: '/tests/factories/user.php'.
You must tell FactoryMuffin to load these factories
public static function setupBeforeClass() { FactoryMuffin::setSaveMethod('save'); FactoryMuffin::loadFactories(__DIR__ . '/factories'); }
Using "setSaveMethod" allows us to modify which function is used when saving the objects to the DB.
Now that our definitions have been created, we can go ahead and use these to create objects in our tests.
function testNetworkHasDescription() { $user = FactoryMuffin::instance('User'); /** * User Object * ( * [username] => qdfaaapozu * [password] => ipbwhlvvzq * [email] => hagenes.bo@mayert.com * [address] => 6654 Howe Point * ) */ }
Because we are calling ::instance(), FactoryMuffin will not try and persist this to the DB.
Factory Muffin can attempt to persist these objects to the DB.
function testNetworkHasDescription() { $user = FactoryMuffin::create('User'); }
You do this by using ::create(). We do this by calling ->save() on the object after creating it.
When calling create/instance, you are able to overwrite values set in the definitions file.
function testOverwritingNetwork() { $user = FactoryMuffin::instance('User', [ 'username' => 'scott' ]); /** * User Object * ( * [username] => scott * [password] => mhygetwsfj * [email] => theodore61@wisoky.biz * [address] => 7091 Luis Row * ) */ }
You can have a factory create a factory within itself, and capture the ID to store in the DB
FactoryMuffin::define( 'Profile', array( 'profile' => 'text', ) );
FactoryMuffin::define( 'User', array( 'username' => 'string', 'password' => 'string', 'email' => 'email', 'address' => 'streetAddress', 'profile_id' => 'factory|Profile' ) );
By creating a User factory, we will now go ahead and create the Profile factory, and return its ID automatically
function testFactoryInception() { $user = FactoryMuffin::create('User'); $profile = Profile::find($user->profile_id); /** * Profile Object * ( * [profile] => Aut optio omnis quia voluptatem. * ) */ }
You can have Factory Muffin call static methods while creating the data sets.
FactoryMuffin::define( 'User', array( 'username' => 'string', 'hash' => 'call|makeHash|string' ) );
class User { public static function makeHash($seed) { return hash('sha256', $seed); } }
Notice that we are passing a randomly generated string into ::makeHash()
And now, when we create the Factory we are provided with a random hash too
function testFactoryInception() { $user = FactoryMuffin::create('User'); /** * User Object *( * [username] => nxqgclrhgk * [hash] => d7e58c93348905ca451ad44c6b22407444e19d32fc59d597d863373196341bfc * ) */ }
All objects that are saved to the DB are tracked.
function tearDownAfterClass() { $objects = FactoryMuffin::saved(); }
This will return an array of all saved objects
You can remove all tracked objects in one go.
function tearDownAfterClass() { FactoryMuffin::setDeleteMethod('delete'); FactoryMuffin::deleteSaved(); }
This will loop over all of the objects and call ->delete() on them.