factory_boy
factory_boy copied to clipboard
How to randomly null fields
I'm probably missing something obvious, but I've been through the documentation a few times, and I can't find a way to sometimes assign None to a nullable field. (My specific case is a field that is sometimes a date and sometimes empty.) What is the correct way to do this? Is it in the documentation?
I do not think there’s a built-in way to make None
values appear for any given factory. Tests are easier to understand and maintain when they use deterministic or predictable values.
A couple idea if you really want to generate None
:
- use
factory.Iterator
with an iterable that containsNone
[datetime.date(2019, 1, 1), datetime.date(2019, 2, 1), None]
date = factory.LazyFunction(lambda: datetime.date.today() if random.random() > 0.3 else None)
For future reference, please try to keep issue for issues with Factory Boy and post to stack overflow to get help on its usage. https://stackoverflow.com/questions/tagged/factory-boy
@alicederyn does that solve your issue?
If you feel that this kind of examples should appear in the docs, we'll be very happy to welcome new contributions (for instance in the recipes
section?) :wink:
I'd like to see this popping up in the documentation somewhere. I'm a Django developer and use FactoryBoy in combination with Faker to generate large sets of mock data. Especially for fields that are allowed to be be blank/null I think it's vital to be able to have sometimes have those fields randomly set to None
by FactoryBoy (or Faker).
For example: if I allow someone to (optionally) upload a profile picture, I should be able to generate both None
and random images. I'm trying this now by using
avatar = LazyFunction(lambda: ImageField(width=500, height=200, color=Faker("color")) if random() > .5 else None)
but calling the factory using this field then fails with
AttributeError: 'ImageField' object has no attribute '_committed'
Adding to my previous comment, I'm now using the solution suggested at https://stackoverflow.com/questions/60957904/optional-nullable-value-for-factory-from-factory-boy which works, so I'm not touching my factory anymore :)
Still wondering what the developers of Factory Boy think would be the best way to go here, though.
Oh, looks like I missed that question :)
The simplest would be:
avatar = factory.Maybe(
factory.Faker('pybool'),
factory.ImageField(width=500, height=200, color=factory.Faker('color')),
)
The doc does not highlight the fact that the decider of Maybe
could be an arbitrary value. In the doc, it looks like it must be a field name.
I also did not get that the yes_declaration
or no_declaration
were optional...
@FractalWire that's a good point; I guess the doc could be improved there. Time is always the issue there :D