pythonfastapifixturesfactory-boy

Async solution for factory boy style fixtures in FastAPI?


I really like the factory boy style of generated factories that can handle things like sequences, complex relationships etc.

For a FastAPI app with fully async database access using factory boy seems likely problematic. There is dated discussion here and an old PR to add async support that seems stuck.

Is there a good solution for these kinds of fixtures that has full async support?


Solution

  • I haven't seen further progress from factory boy on this issue, but ultimately implemented a solution using pytest fixtures as factories that is working well for me.

    The core idea is to build fixtures that return a factory method that can be used in tests. Here is a concrete example that generates users:

    @pytest.fixture(scope="function")
    def user_factory(db: Session):
        """A factory for creating users"""
        last_user = 0
    
        def create_user(
            email=None, name=None, role=None, org: Organization | None = None
        ) -> User:
            """Return a new user, optionally with role for an existing organization"""
            nonlocal last_user
            last_user += 1
            email = email or f"user{last_user}@example.com"
            name = name or f"User {last_user}"
            user = User(email=email, name=name, auth_id=auth_id)
            db.add(user)
    
            if role:
                role = OrganizationRole(user_id=user_id, organization_id=org.id, role=role)
                db.add(role)
    
            db.commit()
            db.refresh(user)
            return user
    
        return create_user
    
    # use in test 
    def test_something(user_factory) -> None:
      user = user_factory()
      # ...
    

    I picked an example with SQLAlchemy ORM for simplicity of demonstrating the concept but you can persist however you like, pull in other factories as dependencies, etc.

    There is a pretty good discussion of how to approach this in this article about using factories as fixtures.

    This article also has good ideas for how to address sequences, constraints and a lot of the things I would use factory boy for by just using simple python.