如何解决Django 测试 - 带有 create_batch
好的,我的测试文件遇到了有趣的问题。
我正在使用这个简单的代码来检查用户创建的 UserFactory
UserFactory.create_batch(4)
for u in User.objects.all():
print(u.email)
UserFactory - 这很好用
在 create_batch(4)
进程中创建 4 个用户
from django.contrib.auth import get_user_model
from factory import Faker
from factory.django import DjangoModelFactory
class UserFactory(DjangoModelFactory):
email = Faker("email")
password = Faker(
"password",length=42,special_chars=True,digits=True,upper_case=True,lower_case=True,)
class Meta:
model = get_user_model()
django_get_or_create = ["email"]
UserFactory - 这个不起作用
在 create_batch(4)
进程中仅创建 1 个用户
from django.contrib.auth import get_user_model
from faker import Faker
from factory.django import DjangoModelFactory
fake = Faker()
class UserFactory(DjangoModelFactory):
email = fake.email()
password = fake.password()
class Meta:
model = get_user_model()
django_get_or_create = ["email"]
唯一的区别是我生成用户电子邮件的方式。 factory.Faker("email)
工作正常,但 faker.email()
不行。
也许有人有同样的问题?
- factory_boy 文档:https://factoryboy.readthedocs.io/en/stable/index.html
- faker 软件包文档:https://faker.readthedocs.io/en/master/index.html
解决方法
您的问题来自 Python 的工作方式。
当您编写以下内容时:
class Foo(Bar):
email = fake.email()
name = fake.name()
或多或少会发生什么:
-
Python 调用
fake.email()
,并接收一个值(比如jane@example.org
) -
Python 调用
fake.name()
,并接收一个值(例如"Johannes"
) -
Python 为目标类构建所有类级声明的字典——这里是
{"email": "jane@example.org","name": "Johannes"}
-
这被传递给
type
以创建类:Foo = type( "Foo",# Name of the class being created [Bar],# List of its bases {"email": "jane@example.org","name": "Johannes"},# Methods & attributes )
-
类现已定义,可用于其余代码。
换句话说,这些行的执行方式与以下代码相同:
fake = faker.Faker()
fake_email = fake.email()
fake_name = fake.name()
class UserFactory(DjangoModelFactory):
email = fake_email
name = fake_name
...
如您所见,UserFactory
从对 faker 的调用接收结果,它无法知道这些值是如何生成的。
这就是各种声明(factory.LazyAttribute
、factory.Faker
等)的原因:在这里,我们使用自定义方法传递工厂特定的对象,每当有新实例时,FactoryBoy 的构建器代码都会调用该方法需要建设:
fake_email_maker = factory.Faker("email")
fake_name_maker = factory.Faker("name")
class UserFactory(DjangoModelFactory):
email = fake_email_maker
name = fake_name_maker
...
当您调用 UserFactory()
时,发生的情况如下所示:
# UserFactory()
>>> fields = {}
>>> fields["name"] = UserFactory._meta.declarations...name.evaluate(...)
>>> fields["email"] = UserFactory._meta.declarations...evaluate(...)
>>> return User.objects.create(**fields)
,
每次获得相同密码的原因是您只获得对 fake.password()
的调用的值。仅在导入文件时调用一次。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。