litestar-org/polyfactory

Allow access to sub-factory fields from build method.

Closed this issue · 2 comments

It would be great to be able to customize the field of a sub-factory (or sub-sub-factory, etc.) right from the parent's build method. For example:

class Bar(BaseModel):
    x: int

class Foo(BaseModel):
    a: int
    bar: Bar

class FooFactory(ModelFactory):
    __model__ = Foo

test_foo = FooFactory.build(bar__x=42)

print(f'{test_foo!r}')  # prints Foo(a=9817, bar=Bar(x=42))

A real example of code that I have to write is something like this:

def test_the_lambda_handler(item_of_interest_fixture):
    test_event = SqsModelFactory.build((Records=[
        SqsRecordsFactory.build(
            body=WebhookEventFactory.build(
                details=WebhookEventDetailsFactory.build(resource_id=item_of_interest_fixture.id)
            ).json()
        )
    ]))

I'd love to be able to do something like this:

def test_the_lambda_handler(item_of_interest_fixture):
    test_event = SqsModelFactory.build(
        Records = SqsRecordsFactory.batch(size=1, body__details__resource_id=item_of_interest_fixture.id)
    )

Everything else can be either the default values or whatever I've customized in the various sub-factories and the test has the value I'm interested in.

I can see the use for this. Its very djangoese though. Why not use dot notation instead?

body__details__resource_id ==> body.details.resource.id

Either way, I am fine with this being implemented - if the implementation is clean and not overly complex.

I was under the impression that the the partial attributes recently implemented was to solve this.
would go like

    test_event = SqsModelFactory.build(
        Records = [{"body": {"details": {"resource_id": item_of_interest_fixture.id}}}]
    )