I have a factoryboy factory for sqlalchemy model which uses faker
from faker import Faker
from db_init import session
fake = Faker()
class ClientAppFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = ClientApp
sqlalchemy_session = session
sqlalchemy_session_persistence = 'commit'
name = fake.word()
display_name = fake.word()
This factory creates rows in database. Field name
of my model must be unique. When I call my factory several times in a row, I get several instances with the same name. How can I get different names in my instances?
import pytest
from pytest_factoryboy import register
register(ClientAppFactory)
@pytest.fixture
def several_client_apps():
ca1 = client_app_factory()
ca2 = client_app_factory()
In this case I get error about name field unique constraint.
I found an answer. Factory has method build which redefine factory attributes every time when you call it.
@pytest.fixture
def several_client_apps():
ca1 = client_app_factory.build()
ca2 = client_app_factory.build()
This is a common mistake with factoryboy
and `faker.
Using faker.Faker
in a Factory will establish a fixed value on the definition of the class. What you want instead is to use factory.Faker
or delay any faker.Faker
execution with a lazy function.
An example with both strategies:
from faker import Faker
import factory
fake = Faker()
word_list = ["one", "two", "three"]
class ExampleFactory(factory.DictFactory):
name = factory.Faker("word")
display_name = factory.LazyFunction(fake.word)
another_name = factory.LazyFunction(lambda: fake.word(word_list))
ExampleFactory.bu()
ExampleFactory.create_batch(5)
I used a DictFactory
to make it simpler to test, but it should work with model-based factories too.
The another_name
field uses a lambda to be able to add parameters to the fake method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.