Forge will create objects based on factory data. It should be used when you don't want a database, ie. unit tests, but want fully fleshed objects that act like database objects.
To keep things organized, I recommend creating a test/factories
directory where all of your factory files will go. For example
project '- test '- factories |- __init__.py |- user.py |- post.py `- comment.py
We'll use the user.py
factory from above for example. There are two ways to define a factory. The first is just a normal method call to Forge.define
:
# project/test/factories/user.py from forge import Forge Forge.define('user', name='Guy')
The other is using the with
syntax:
# project/test/factories/user.py from forge import Forge with Forge.define('user') as f: f.name = 'Guy' f.age = 25 f.login = "personguy" f.email = "[email protected]" f.password = "testing"
My suggestion is to use the normal syntax when defining a small factory. Essentially, when the definition can fit on one line. Use the with
syntax when setting a large number of default attributes. Putting each attribute on it's own line mirrors how models are declared and makes it easy to quickly grock a Model and it's matching Factory.
Building factory objects is easy; just call Forge.build
with the factory name.
user = Forge.build('user')
You can also use the shorthand version:
user = Forge('user')
If all you want is the raw dict
of attributes for a particular factory, use Forge.attributes_for
.
Forge.attributes_for('user') #=> {'name': 'Guy', 'age': 25, 'login': 'personguy', ... }
No magic here, just set an attribute to another Forged object:
Forge.define('car', owner=Forge('user'))
In project/test/factories/__init__.py
, import all your other factories, so you won't have to later in your tests:
# project/test/factories/__init__.py import user, post, comment
Now, in your unit tests:
# project/test/user_test.py import project.test.factories from forge import Forge class UserTest(TestCase): def setUp(self): self.user = Forge('user') def test_users_name_is_guy(self): assert self.user.name == 'Guy'