summaryrefslogtreecommitdiff
path: root/docs/examples.rst
blob: 6f26b7ed4c86a53ed6ee4ef723bfcfdfefee1dc5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
Examples
========

Here are some real-world examples of using FactoryBoy.


Objects
-------

First, let's define a couple of objects:


.. code-block:: python

    class Account(object):
        def __init__(self, username, email):
            self.username = username
            self.email = email

        def __str__(self):
            return '%s (%s)' % (self.username, self.email)


    class Profile(object):

        GENDER_MALE = 'm'
        GENDER_FEMALE = 'f'
        GENDER_UNKNOWN = 'u'  # If the user refused to give it

        def __init__(self, account, gender, firstname, lastname, planet='Earth'):
            self.account = account
            self.gender = gender
            self.firstname = firstname
            self.lastname = lastname
            self.planet = planet

        def __unicode__(self):
            return u'%s %s (%s)' % (
                unicode(self.firstname),
                unicode(self.lastname),
                unicode(self.account.accountname),
            )

Factories
---------

And now, we'll define the related factories:


.. code-block:: python

    import datetime
    import factory
    import random

    from . import objects


    class AccountFactory(factory.Factory):
        class Meta:
            model = objects.Account

        username = factory.Sequence(lambda n: 'john%s' % n)
        email = factory.LazyAttribute(lambda o: '%s@example.org' % o.username)
        date_joined = factory.LazyFunction(datetime.datetime.now)


    class ProfileFactory(factory.Factory):
        class Meta:
            model = objects.Profile

        account = factory.SubFactory(AccountFactory)
        gender = factory.Iterator([objects.Profile.GENDER_MALE, objects.Profile.GENDER_FEMALE])
        firstname = u'John'
        lastname = u'Doe'



We have now defined basic factories for our :class:`~Account` and :class:`~Profile` classes.

If we commonly use a specific variant of our objects, we can refine a factory accordingly:


.. code-block:: python

    class FemaleProfileFactory(ProfileFactory):
        gender = objects.Profile.GENDER_FEMALE
        firstname = u'Jane'
        user__username = factory.Sequence(lambda n: 'jane%s' % n)



Using the factories
-------------------

We can now use our factories, for tests:


.. code-block:: python

    import unittest

    from . import business_logic
    from . import factories
    from . import objects


    class MyTestCase(unittest.TestCase):

        def test_send_mail(self):
            account = factories.AccountFactory()
            email = business_logic.prepare_email(account, subject='Foo', text='Bar')

            self.assertEqual(email.to, account.email)

        def test_get_profile_stats(self):
            profiles = []

            profiles.extend(factories.ProfileFactory.create_batch(4))
            profiles.extend(factories.FemaleProfileFactory.create_batch(2))
            profiles.extend(factories.ProfileFactory.create_batch(2, planet="Tatooine"))

            stats = business_logic.profile_stats(profiles)
            self.assertEqual({'Earth': 6, 'Mars': 2}, stats.planets)
            self.assertLess(stats.genders[objects.Profile.GENDER_FEMALE], 2)


Or for fixtures:

.. code-block:: python

    from . import factories

    def make_objects():
        factories.ProfileFactory.create_batch(size=50)

        # Let's create a few, known objects.
        factories.ProfileFactory(
            gender=objects.Profile.GENDER_MALE,
            firstname='Luke',
            lastname='Skywalker',
            planet='Tatooine',
        )

        factories.ProfileFactory(
            gender=objects.Profile.GENDER_FEMALE,
            firstname='Leia',
            lastname='Organa',
            planet='Alderaan',
        )