Factory boy makes it easy to create objects when you need them for tests.For example..
lets say you have this set of models,
from django.db import models
class Owner(models.Model):
name = models.CharField(max_length=200)
phone = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Car(models.Model):
name = models.CharField(max_length=200)
owner = models.ForeignKey(Owner)
def __unicode__(self):
return self.name
Then your factories.py for these two will correspond to something like this
import factory
from models import Owner, Car
class OwnerFactory(factory.Factory):
FACTORY_FOR = Owner
name = 'bruce'
phone = '+254728037573'
class CarFactory(factory.Factory):
FACTORY_FOR = Car
name = 'jeep'
owner = factory.lazy_attribute(lambda a: OwnerFactory())
The tests for the factories themselves go something like this
from models import Car,OwnerMany to many fields are a bit tricky to emulate but this does the trick. For instance lets say you have this set of models.
from django.test.testcases import TestCase
class FactoryTestCase(TestCase):
def test_car_factory(self):
car = CarFactory()
self.assertTrue(isinstance(car, Car))
def test_owner_factory(self):
owner = OwnerFactory()
self.assertTrue(isinstance(owner, Owner))
from django.db import models
class Pizza(models.Model):
name = models.CharField(max_length=120)
toppings = models.ManyToManyField(Topping)
def __unicode__(self):
return self.name
class Topping(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
Then your factories will go something like this.
So the key here is to override the _prepare method and assign the manytomanyfield objects here, since you have and instance of the object. In conclusion factories are a good alternative to fixtures when used in the right way.
from models import Pizza, Topping
import factory
class ToppingFactory(factory.Factory):
FACTORY_FOR = Topping
name = 'mushrooms'
class PizzaFactory(factory.Factory):
FACTORY_FOR = Pizza
name = 'mushroom delight'
@classmethod
def _prepare(cls, create, **kwargs):
topping = ToppingFactory()
pizza = super(PizzaFactory, cls)._prepare(create, **kwargs)
pizza.toppings.add(topping)
return pizza