0
# Core Factory Classes
1
2
Essential factory classes that form the foundation of Factory Boy's object generation capabilities. These classes support different build strategies and provide the base functionality for creating test objects.
3
4
## Capabilities
5
6
### Main Factory Class
7
8
The primary factory class supporting build, create, and stub strategies with batch operations and sequence management.
9
10
```python { .api }
11
class Factory:
12
"""
13
Base factory class for creating objects with customizable attributes.
14
15
Meta attributes:
16
- model: The class to instantiate
17
- strategy: Default strategy ('build', 'create', 'stub')
18
- abstract: Set to True for abstract factories
19
"""
20
21
def build(**kwargs):
22
"""
23
Build instance without persistence.
24
25
Args:
26
**kwargs: Override default attribute values
27
28
Returns:
29
Instance of Meta.model
30
"""
31
32
def create(**kwargs):
33
"""
34
Create and persist instance (calls _create method).
35
36
Args:
37
**kwargs: Override default attribute values
38
39
Returns:
40
Persisted instance of Meta.model
41
"""
42
43
def stub(**kwargs):
44
"""
45
Create stub object with attributes only (no persistence).
46
47
Args:
48
**kwargs: Override default attribute values
49
50
Returns:
51
StubObject with specified attributes
52
"""
53
54
def build_batch(size, **kwargs):
55
"""
56
Build multiple instances without persistence.
57
58
Args:
59
size (int): Number of instances to create
60
**kwargs: Override default attribute values for all instances
61
62
Returns:
63
List of instances
64
"""
65
66
def create_batch(size, **kwargs):
67
"""
68
Create and persist multiple instances.
69
70
Args:
71
size (int): Number of instances to create
72
**kwargs: Override default attribute values for all instances
73
74
Returns:
75
List of persisted instances
76
"""
77
78
def stub_batch(size, **kwargs):
79
"""
80
Create multiple stub objects.
81
82
Args:
83
size (int): Number of stubs to create
84
**kwargs: Override default attribute values for all stubs
85
86
Returns:
87
List of StubObjects
88
"""
89
90
def generate(strategy, **kwargs):
91
"""
92
Generate instance using specified strategy.
93
94
Args:
95
strategy (str): 'build', 'create', or 'stub'
96
**kwargs: Override default attribute values
97
98
Returns:
99
Instance created with specified strategy
100
"""
101
102
def generate_batch(strategy, size, **kwargs):
103
"""
104
Generate multiple instances using specified strategy.
105
106
Args:
107
strategy (str): 'build', 'create', or 'stub'
108
size (int): Number of instances to create
109
**kwargs: Override default attribute values
110
111
Returns:
112
List of instances created with specified strategy
113
"""
114
115
def simple_generate(create, **kwargs):
116
"""
117
Generate instance with boolean create flag.
118
119
Args:
120
create (bool): True for create strategy, False for build
121
**kwargs: Override default attribute values
122
123
Returns:
124
Instance created with specified strategy
125
"""
126
127
def simple_generate_batch(create, size, **kwargs):
128
"""
129
Generate multiple instances with boolean create flag.
130
131
Args:
132
create (bool): True for create strategy, False for build
133
size (int): Number of instances to create
134
**kwargs: Override default attribute values
135
136
Returns:
137
List of instances
138
"""
139
140
def reset_sequence(value=None, force=False):
141
"""
142
Reset sequence counter for this factory.
143
144
Args:
145
value (int, optional): Value to reset to (default: 0)
146
force (bool): Force reset even if not at sequence start
147
"""
148
149
def attributes(create=False, extra=None):
150
"""
151
Build attribute dictionary without creating object instance.
152
(Deprecated - use build() or create() instead)
153
154
Args:
155
create (bool): Whether to use create strategy for attribute resolution
156
extra (dict, optional): Additional attributes to merge
157
158
Returns:
159
dict: Resolved attributes dictionary
160
"""
161
162
# Customization hooks
163
def _build(model_class, *args, **kwargs):
164
"""Override to customize object building."""
165
166
def _create(model_class, *args, **kwargs):
167
"""Override to customize object creation/persistence."""
168
169
def _after_postgeneration(instance, create, results):
170
"""Hook called after post-generation declarations."""
171
```
172
173
#### Usage Examples
174
175
```python
176
# Basic factory definition
177
class UserFactory(Factory):
178
class Meta:
179
model = User
180
strategy = BUILD_STRATEGY # Optional, defaults to CREATE_STRATEGY
181
182
name = 'Test User'
183
email = Sequence(lambda n: f'user{n}@example.com')
184
185
# Using different strategies
186
user1 = UserFactory() # Uses default strategy (create)
187
user2 = UserFactory.build() # Build without persistence
188
user3 = UserFactory.create() # Create with persistence
189
user4 = UserFactory.stub() # Create stub object
190
191
# Batch operations
192
users = UserFactory.build_batch(5)
193
active_users = UserFactory.create_batch(3, is_active=True)
194
195
# Custom strategy
196
user = UserFactory.generate('stub', name='Custom User')
197
```
198
199
### Dictionary Factory
200
201
Factory class for creating Python dictionaries with declared attributes.
202
203
```python { .api }
204
class BaseDictFactory(Factory):
205
"""
206
Abstract base factory for dictionary-like classes.
207
208
Meta attributes:
209
- abstract: Always True for this base class
210
"""
211
212
class DictFactory(BaseDictFactory):
213
"""
214
Concrete factory for creating Python dictionaries.
215
216
Meta attributes:
217
- model: dict
218
"""
219
```
220
221
#### Usage Examples
222
223
```python
224
class ConfigFactory(DictFactory):
225
api_key = Faker('uuid4')
226
timeout = 30
227
enabled = True
228
settings = Dict({
229
'debug': False,
230
'max_retries': Sequence(lambda n: n + 1)
231
})
232
233
config = ConfigFactory()
234
# Returns: {'api_key': '...', 'timeout': 30, 'enabled': True, 'settings': {...}}
235
```
236
237
### List Factory
238
239
Factory class for creating Python lists with declared elements.
240
241
```python { .api }
242
class BaseListFactory(Factory):
243
"""
244
Abstract base factory for list-like classes.
245
246
Meta attributes:
247
- abstract: Always True for this base class
248
"""
249
250
class ListFactory(BaseListFactory):
251
"""
252
Concrete factory for creating Python lists.
253
254
Meta attributes:
255
- model: list
256
"""
257
```
258
259
#### Usage Examples
260
261
```python
262
class TagListFactory(ListFactory):
263
tag1 = Faker('word')
264
tag2 = Faker('word')
265
tag3 = 'default-tag'
266
267
tags = TagListFactory()
268
# Returns: ['random-word1', 'random-word2', 'default-tag']
269
```
270
271
### Stub Factory
272
273
Factory class that only supports stub strategy, useful for creating test objects without any persistence.
274
275
```python { .api }
276
class StubFactory(Factory):
277
"""
278
Factory that only supports stub strategy.
279
280
Meta attributes:
281
- strategy: STUB_STRATEGY
282
- model: StubObject
283
"""
284
285
def create(**kwargs):
286
"""Raises UnsupportedStrategy - not available for stub factories."""
287
288
class StubObject:
289
"""
290
Generic container for attribute storage.
291
292
Args:
293
**kwargs: Attributes to set on the object
294
"""
295
def __init__(self, **kwargs): ...
296
```
297
298
#### Usage Examples
299
300
```python
301
class TestDataFactory(StubFactory):
302
name = 'Test Object'
303
value = Sequence(lambda n: n * 10)
304
metadata = Dict({'created': True})
305
306
# Only stub() works
307
obj = TestDataFactory.stub()
308
# obj.name == 'Test Object', obj.value == 0, etc.
309
310
# This raises UnsupportedStrategy
311
TestDataFactory.create() # Error!
312
```
313
314
### Strategy Decorator
315
316
Decorator function to override the default strategy for a factory class.
317
318
```python { .api }
319
def use_strategy(new_strategy):
320
"""
321
Decorator to force different strategy on factory class.
322
323
Args:
324
new_strategy (str): Strategy to use ('build', 'create', 'stub')
325
326
Returns:
327
Decorator function that modifies factory's default strategy
328
"""
329
```
330
331
#### Usage Examples
332
333
```python
334
@use_strategy(BUILD_STRATEGY)
335
class AlwaysBuildUserFactory(Factory):
336
class Meta:
337
model = User
338
339
name = 'Build User'
340
341
# Even calling create() will use build strategy
342
user = AlwaysBuildUserFactory.create() # Actually builds, doesn't persist
343
```
344
345
## Factory Definition Patterns
346
347
### Basic Factory
348
349
```python
350
class SimpleFactory(Factory):
351
class Meta:
352
model = MyModel
353
354
field1 = 'static value'
355
field2 = Sequence(lambda n: f'value_{n}')
356
```
357
358
### Abstract Factory
359
360
```python
361
class BaseFactory(Factory):
362
class Meta:
363
model = BaseModel
364
abstract = True
365
366
created_at = LazyFunction(datetime.now)
367
is_active = True
368
369
class ConcreteFactory(BaseFactory):
370
class Meta:
371
model = ConcreteModel
372
373
name = Faker('name')
374
```
375
376
### Factory with Custom Hooks
377
378
```python
379
class CustomFactory(Factory):
380
class Meta:
381
model = MyModel
382
383
name = 'Test'
384
385
@classmethod
386
def _create(cls, model_class, *args, **kwargs):
387
"""Custom creation logic."""
388
instance = super()._create(model_class, *args, **kwargs)
389
instance.custom_setup()
390
return instance
391
392
@classmethod
393
def _after_postgeneration(cls, instance, create, results):
394
"""Hook after post-generation."""
395
if create:
396
instance.finalize()
397
```