breadjesus
breadjesus

Reputation: 2059

factory_boy: make a factory that returns the result of a function

I have a function that generates a list of objects. The objects have complex relationships that are handled in the generator function.

How do I make a factory (not a SubFactory!) that, when asked to generate a value, just calls this function?

Upvotes: 0

Views: 86

Answers (1)

Xelnor
Xelnor

Reputation: 3599

Under the hood, a simple factory.Factory will simply call its Meta.model, using the parameters as kwargs.

For instance, in order to call subprocess.run, one could use the following factory:

class ProcessFactory(factory.Factory):
  class Meta:
    model = subprocess.run

  class Params:
    # Require the program being passed separately from its options.
    program = "ls"
    opts = ()

  args = factory.LazyAttribute(lambda o: [o.program] + list(o.opts))

  check = True
  capture_output = True

and use it as:

>>> ProcessFactory(opts=["-a", "-h", "."], cwd="/tmp")
CompletedProcess(...)

As you can see:

  • The factory simply called the function provided in Meta.model, passing all declarations as kwargs, and returned the function's return value;
  • Fields declared in class Params aren't passed to the function;
  • One can freely use all kinds of factory_boy declarations.

If your function expects positional arguments, the Meta.inline_args option can be used to convert kwargs into positional arguments.

Upvotes: 2

Related Questions