summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference.rst46
-rw-r--r--tests/test_declarations.py7
2 files changed, 52 insertions, 1 deletions
diff --git a/docs/reference.rst b/docs/reference.rst
index 85b299c..06eee85 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -847,7 +847,7 @@ InfiniteIterator
-post-building hooks
+Post-generation hooks
"""""""""""""""""""
Some objects expect additional method calls or complex processing for proper definition.
@@ -859,6 +859,49 @@ To support this pattern, factory_boy provides the following tools:
- :class:`RelatedFactory`: this builds or creates a given factory *after* building/creating the first Factory.
+Extracting parameters
+"""""""""""""""""""""
+
+All post-building hooks share a common base for picking parameters from the
+set of attributes passed to the :class:`Factory`.
+
+For instance, a :class:`PostGeneration` hook is declared as ``post``:
+
+.. code-block:: python
+
+ class SomeFactory(factory.Factory):
+ FACTORY_FOR = SomeObject
+
+ @post_generation
+ def post(self, create, extracted, **kwargs):
+ obj.set_origin(create)
+
+.. OHAI_VIM**
+
+
+When calling the factory, some arguments will be extracted for this method:
+
+- If a ``post`` argument is passed, it will be passed as the ``extracted`` field
+- Any argument starting with ``post__XYZ`` will be extracted, its ``post__`` prefix
+ removed, and added to the kwargs passed to the post-generation hook.
+
+Extracted arguments won't be passed to the :attr:`~Factory.FACTORY_FOR` class.
+
+Thus, in the following call:
+
+.. code-block:: pycon
+
+ >>> SomeFactory(
+ post=1,
+ post_x=2,
+ post__y=3,
+ post__z__t=42,
+ )
+
+The ``post`` hook will receive ``1`` as ``extracted`` and ``{'y': 3, 'z__t': 42}``
+as keyword arguments; ``{'post_x': 2}`` will be passed to ``SomeFactory.FACTORY_FOR``.
+
+
RelatedFactory
""""""""""""""
@@ -1048,6 +1091,7 @@ the extracted value must be iterable:
>>> UserFactory() # Calls user.set_password('', 'sha1')
>>> UserFactory(password=('test', 'md5')) # Calls user.set_password('test', 'md5')
+ >>> UserFactory(password__disabled=True) # Calls user.set_password('', 'sha1', disabled=True)
>>> # Always pass in a good iterable:
>>> UserFactory(password=('test',)) # Calls user.set_password('test')
diff --git a/tests/test_declarations.py b/tests/test_declarations.py
index b11a4a8..2e527af 100644
--- a/tests/test_declarations.py
+++ b/tests/test_declarations.py
@@ -355,6 +355,13 @@ class PostGenerationMethodCallTestCase(unittest.TestCase):
decl.call(self.obj, False, (('param1', 'param2'),))
self.obj.method.assert_called_once_with(('param1', 'param2'))
+ def test_multi_call_with_kwargs(self):
+ decl = declarations.PostGenerationMethodCall(
+ 'method', 'arg1', 'arg2')
+ decl.call(self.obj, False, x=2)
+ self.obj.method.assert_called_once_with('arg1', 'arg2', x=2)
+
+
class CircularSubFactoryTestCase(unittest.TestCase):