I'm building a factory with factory_boy that generates a django model. I would like to see what arguments the user inputs inline. My factory itself looks like this
class SomeFactory(factory.django.DjangoModelFactory):
name = factory.Sequence(lambda n: 'Instance #{}'.format(n))
some_other_thing = factory.SubFactory(SomeOtherFactory)
class Meta:
model = SomeModel
Now the user could say s = SomeFactory() and it would work fine, but I want to detect if the user input their own argument. For instance, to tell if the user passed in their own name, as in s = SomeFactory(name='Matt')
What I've tried so far is
__init__ function in the SomeFactory class
s = SomeFactory(), nor when I call s.__init__()
__new__ method_adjust_kwargs
kwargs, not just the ones the user defined. For instance, calling s = SomeFactory(name='Matt'), I would get a kwargs dict with keys for name and some_other_thing, which makes it impossible to tell input their own argument or not_create
_adjust_kwargs, in that kwargs doesn't contain the original kwargs, but rather all of the argumentsI think a lot of the functionality I'm after is black-boxed inside of factory_boy's StepBuilder (I suspect it's in the instantiate method) but I have no idea how to modify it to do what I want.
Does anyone have any thoughts on how to figure out which kwargs were set originally in the call to s = SomeFactory()? I.e. determine that if I said s = SomeFactory(name='Matt'), that the user manually set the name?
Thanks!
Update: I'm running django version 1.11.2, factory_boy version 2.8.1, and python version 3.5.2
You can override the create method to only get the user kwargs.
A full example would be something like this:
from django.contrib.auth.models import User
import factory
class UserFactory(factory.DjangoModelFactory):
username = factory.Sequence(
lambda n: 'test'
)
email = factory.Sequence(lambda n: 'user{0}@example.com'.format(n))
class Meta:
model = User
@classmethod
def create(cls, **kwargs):
# here you'll only have the kwargs that were entered manually
print(str(kwargs))
return super(UserFactory, cls).create(**kwargs)
So when I call it:
In [2]: UserFactory(username='foobar')
{'username': 'foobar'}
Out[2]: <User: foobar>
If you want to catch kwargs for other build strategies than create, you would also need to do this for the stub and build method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With