django 如何使用来自Factory_boy的骗子

km0tfn4u  于 2023-03-04  发布在  Go
关注(0)|答案(5)|浏览(142)

Factory_boy使用fake-factory (Faker)生成随机值,我想在Django测试中直接使用Faker生成一些随机值。
Factory_boy docs建议使用factory.Faker及其提供程序:

class RandomUserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = factory.Faker('first_name')

但这不会生成任何名称:

>>> import factory
>>> factory.Faker('name')
<factory.faker.Faker object at 0x7f1807bf5278>
>>> type(factory.Faker('name'))
<class 'factory.faker.Faker'>

factory_boyfaker.pyfactory.Faker('ean', length=10)调用faker.Faker.ean(length=10),但是Faker文档说它应该显示一个名称:

from faker import Faker
fake = Faker()
fake.name()
# 'Lucy Cechtelar'

除了直接从Faker设置示例之外,是否还有其他方法可以使用Faker

from faker import Factory
fake = Factory.create()
fake.name()
atmip9wb

atmip9wb1#

可以像这样将faker与factory_boy一起使用:

class RandomUserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = factory.Faker('first_name')

user = RandomUserFactory()

print user.first_name
# 'Emily'

因此,您需要使用factory_boy示例化一个用户,它将为您调用Faker。
我不知道您是否会尝试在Django中使用这个函数,但是如果您希望工厂将创建的用户保存到数据库中,那么您需要扩展factory.django.DjangoModelFactory而不是factory.Factory。

66bbxpm5

66bbxpm52#

我知道这是一个老问题,但对于任何可能遇到这个问题的人,这里有另一种方法,你可以使用。

>>> from factory.faker import faker
>>> FAKE = faker.Faker()
>>> FAKE.name()
'Scott Rodriguez'
>>> FAKE.address()
'PSC 5061, Box 1673\nAPO AP 53007'
>>>
xmd2e60i

xmd2e60i3#

factory_boy不提供公共/文档化的接口来访问它使用的Faker示例,所以最好创建一个单独的接口,但如果你真的需要:

import factory
print(factory.Faker._get_faker().random_int())
print(factory.Faker._get_faker('en_US').random_int())

您也可以使用generate()/evaluate(),但接口会随时间而变化:

# 3.0.1
# uses self.locale
print(factory.Faker('random_int').generate())
print(factory.Faker('random_int').evaluate(None, None, None))
print(factory.Faker('random_int', locale='en_US').generate())
print(factory.Faker('random_int', locale='en_US').evaluate(None, None, None))

# 3.1.0
# uses locale from the parameters
print(factory.Faker('random_int').generate({'locale': None}))
print(factory.Faker('random_int').evaluate(None, None, {'locale': None}))
print(factory.Faker('random_int').generate({'locale': 'en_US'}))
print(factory.Faker('random_int').evaluate(None, None, {'locale': 'en_US'}))

# 3.2.0, 3.2.1
# no generate()
print(factory.Faker('random_int').evaluate(None, None, {'locale': None}))
print(factory.Faker('random_int').evaluate(None, None, {'locale': 'en_US'}))

您还可以查看the other answer以获得更详细的示例。

qnakjoqk

qnakjoqk4#

首先,如果你想在Django模型中使用factory_boy,你应该使用推荐的DjangoModelFactory
其次,factory_boy还建议使用Faker属性声明,以便轻松定义看起来逼真的工厂。

class RandomUserFactory(factory.DjangoModelFactory):
    class Meta:
        model = 'myapp.User'  # Equivalent to model = myapp.models.User

    first_name = factory.Faker('first_name')

一旦定义了工厂,就可以简单地按如下方式使用它:

>>> o = RandomUserFactory()
>>> o.first_name
Tim
sauutmhj

sauutmhj5#

正如其他答案已经阐明的那样,使用Faker的正确/通常方式是与工厂一起使用,然而,能够内联使用Faker偶尔也会有用,这似乎是这里的根本问题。
以下是2022年及最新factoryboy版本的更新答案:

from typing import Any

from factory import Faker

def get_fake(provider: str, locale: str | None = None) -> Any:
     """ e.g. `get_fake('name')` ==> 'Buzz Aldrin' """
    if not locale:
        locale = Faker._DEFAULT_LOCALE  # pylint: disable=protected-access
    return Faker(provider).evaluate({}, None, {'locale': locale})

相关问题