Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Faker from Factory_boy

Factory_boy uses fake-factory (Faker) to generate random values, I would like to generate some random values in my Django tests using Faker directly.

Factory_boy docs suggests using factory.Faker and its provider as :

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

    first_name = factory.Faker('first_name')

But this isn't generating any name:

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

From factory_boy faker.py class factory.Faker('ean', length=10) calls faker.Faker.ean(length=10) but Faker docs says it should show a name:

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

Is there any other way to use Faker instead of setting an instance directly from Faker?

from faker import Factory
fake = Factory.create()
fake.name()
like image 363
marcanuy Avatar asked Jul 31 '16 19:07

marcanuy


People also ask

What is Factory_boy?

factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard to maintain fixtures with easy-to-use factories for complex objects.


4 Answers

You can use faker with factory_boy like this:

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

    first_name = factory.Faker('first_name')

user = RandomUserFactory()

print user.first_name
# 'Emily'

So you need to instantiate a user with factory_boy and it will call Faker for you.

I don't know if you are trying to use this with Django or not, but if you want the factory to save the created user to the database, then you need to extend factory.django.DjangoModelFactory instead of factory.Factory.

like image 137
rlaszlo Avatar answered Oct 21 '22 04:10

rlaszlo


I know this is an old question but for anyone who might come across this, here's another approach that you can use.

>>> from factory.faker import faker
>>> FAKE = faker.Faker()
>>> FAKE.name()
'Scott Rodriguez'
>>> FAKE.address()
'PSC 5061, Box 1673\nAPO AP 53007'
>>>
like image 31
domino Avatar answered Oct 21 '22 02:10

domino


UPD You should generally prefer one of the two other answers, because this ones uses the private interface, and the generate() solution only works for factory-boy<3.1.0.

A bit simpler way is to use undocumented generate() method (factory-boy<3.1.0):

import factory
print(factory.Faker('random_int').generate({}))

or _get_faker():

print(factory.Faker._get_faker().random_int())

You may check out the other answer for a more detailed example.

like image 8
x-yuri Avatar answered Oct 21 '22 03:10

x-yuri


First, if you want to use factory_boy with a Django model, you should use DjangoModelFactory as it is recommended.

Second, factory_boy also suggests to use Faker attribute declaration in order to easily define realistic-looking factories. (see providers)

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

    first_name = factory.Faker('first_name')

Once you have defined your factory, you can simply use it as follows:

>>> o = RandomUserFactory()
>>> o.first_name
Tim
like image 4
lmiguelvargasf Avatar answered Oct 21 '22 04:10

lmiguelvargasf