factory_boy
factory_boy copied to clipboard
Allow traits based on a value
Hi, first off tip of the hat for a awesome library.
The parameter example uses duration='short'|'long'
, but Traits only accepts booleans. It would be useful to allow Traits based on some (arbitrary) value rather then just a boolean. Like the duration
example.
In my case I have a polymorphic* model, and would like to switch based on a value from an enum. Not quite sure about the interface here, but something like:
class Factory(factroy.Factory):
class Meta:
model = Order
state = 'created'
created_on = datetime.today()
paid_on = None
canceled_on = None
fulfilled_on = None
returned_on = None
class Params:
status = factroy.Trait(
created=dict(
state='created',
created_on=datetime.today()
),
paid=dict(
state='paid',
paid_on=datetime.today()
),
canceled=dict(
state='canceled',
canceled_on=datetime.today()
),
fulfilled=dict(
state='fulfilled',
fulfilled_on=datetime.today()
),
returned=dict(
state='returned',
returned_on=datetime.today()
)
)
* It's unfortunately doesn't use the polymorphic support in Django, but it's an homegrown solution.
I like the idea :)
We should have thought about it before implementing the Trait
in the first place, now we'll need to design a simple migration path though :disappointed:
Regarding the API, I'd like to find a way to protect users from spelling errors; what about the following proposal:
status = factory.Switch({
OrderStatus.CREATED: factory.Trait(
state=OrderStatus.CREATED,
created_on=factory.LazyFunction(datetime.today),
),
OrderStatus.PAID: factory.Trait(
state=OrderStatus.PAID,
created_on=factory.LazyFunction(datetime.today),
),
})
Pros:
- Using a dict allows to share constants between the declaration section and using it;
- Reusing the
factory.Trait
reuses existing concepts: a switch will simply enable one of several traits
Cons:
- More verbose than what you proposed :wink:
I like it. I hadn't thought about using something else the strings, which yours solves neatly.
If you want to DRY something up, just add a helper function, that's my philosophy anyways 😀
To be more concrete, I have a model with two foreign keys (for now...), but only one should be set at any given time. I added a Params to select which type, at the point in time it doesn't know if it's building or creating. In the end I always build the subfactory, and in a post_generation hook to conditionally save which ever was built previously. But it's kinda hacky and feels wrong somehow.
Hi! Is there any progress on this feature?
+1