FactoryBoy / factory_boy

A test fixtures replacement for Python
https://factoryboy.readthedocs.io/
MIT License
3.48k stars 392 forks source link

Document how to use Faker inside LazyAttribute #915

Open mcosta74 opened 2 years ago

mcosta74 commented 2 years ago

The problem

The class factory.Faker is a wrapper around the "real" Faker. It works fine but sometimes you need to use it inside a LazyAttribute and you need to generate a value.

At the moment I use a trick like

class MyFactory(factory.Factory):
    class Params:
        user = None

    @factory.lazy_attribute
    def current_ip_address(obj):
        if obj.user:
            return obj.user.ip_address
        else:
            return factory.Faker('ipv4').evaluate(None, None, {'locale': factory.Faker._DEFAULT_LOCALE})

Proposed solution

In some cases I can use Maybe but not always. Would be nice to have a section in the documentation that explain how to use Faker in LazyAttribute

rbarrois commented 2 years ago

It's currently not supported, indeed. The code you're using is a private API.

Instead, you could use:

class MyFactory(factory.Factory):
    class Params:
        fallback_ip_address = factory.Faker("ipv4")

    current_ip_address = factory.LazyAttribute(
        lambda o: o.user.ip_address if o.user else o.fallback_ip_address,
    )
mcosta74 commented 2 years ago

thanks for the reply, maybe a note in documentation might help

nmaynes commented 2 years ago

I am in the midst of implementing a testing suite built on SQLAlchemy and Factory Boy. There are a number of small updates I would like to add to the documentation, specifically for users trying to use Factory Boy with SQLAlchemy directly. I do not mind including this update to the documentation with my planned PR. That is, unless someone else wants to take it.