The original kwargs factory_boy

I am creating a factory with factory_boy

that creates a django model. I would like to see what arguments the user enters into the string. 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 can tell s = SomeFactory()

and it will work fine, but I want to detect if the user is entering their own argument. For example, to find out if the user passed their name, as ins = SomeFactory(name='Matt')

I have tried so far

  • Writing my own function __init__

    in a classSomeFactory

    • This is mysteriously overwritten and not called when I call s = SomeFactory()

      , and when I calls.__init__()

  • The same happens for method rewriting __new__

  • Rewriting the ill-named _adjust_kwargs

    • This gives me all the fields as kwargs

      , not just the ones the user has defined. For example, by calling s = SomeFactory(name='Matt')

      , I would get a kwargs

      dict with keys for name

      and some_other_thing

      , which makes it impossible to specify the input of their own argument or not
  • Overwrite _create

    • There is still a problem with overwriting _adjust_kwargs

      as it kwargs

      does not contain the original kwargs

      , but rather all the arguments

I think a lot of the functionality I use after this has a black box inside factory_boy

StepBuilder

(I suspect this is in the method instantiate

), but I don't know how to change it to do what I want.

Does anyone have any thoughts on how to determine which ones kwargs

were originally set in the call s = SomeFactory()

? That is, what if I said s = SomeFactory(name='Matt')

that the user manually set the name?

Thank!

Update: I am running django

version 1.11.2

, factory_boy

version 2.8.1

and python

version3.5.2

+3


source to share


1 answer


You can override the method create

to only get custom kwargs.

A complete 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 will also need to do that for the stub

and methods build

.

+1


source







All Articles