summaryrefslogtreecommitdiff
path: root/docs/examples.rst
blob: cac6bc689ed23f161fd454e1829a703ce74cd1bf (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
Examples
========

Here are some real-world examples of using FactoryBoy.


Objects
-------

First, let's define a couple of objects::

    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::

    import factory
    import random

    from . import objects


    class AccountFactory(factory.Factory):
        FACTORY_FOR = objects.Account

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


    class ProfileFactory(factory.Factory):
        FACTORY_FOR = objects.Profile

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



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

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

    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::

    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 = []

            for _ in xrange(4):
                profiles.append(factories.ProfileFactory())
            for _ in xrange(2):
                profiles.append(factories.FemaleProfileFactory())
            for _ in xrange(2):
                profiles.append(factories.ProfileFactory(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::

    from . import factories

    def make_objects():
        for _ in xrange(50):
            factories.ProfileFactory()

        # 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',
        )