我有一个 Django 模型,定义如下:
class CustomModel(models.Model):
column = models.CharField(max_length=50, unique=True)
Run Code Online (Sandbox Code Playgroud)
为模型定义工厂
from factory_boy import DjangoModelFactory
class CustomModelFactory(DjangoModelFactory):
column = 'V1'
FACTORY_FOR = CustomModelFactory()
Run Code Online (Sandbox Code Playgroud)
我如何确保工厂每次都实现 get_or_create 而不是创建?
有谁知道如何做到这一点?
我有以下工厂:
class ContactFactory(DjangoModelFactory):
name = Faker('company')
industry = Iterator(Industry.objects.all())
class Meta:
model = 'sales.contact'
@post_generation
def requested_devices(self, create, extracted, **kwargs):
if create:
self.requested_devices.add(MSize.objects.first())
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写一个测试,例如:
class TestUserCanAskQuestion(TestCase):
@classmethod
def setUpTestData(cls):
call_command('insert_initial_data')
def setUp(self):
self.contact = ContactFactory()
Run Code Online (Sandbox Code Playgroud)
但每次我运行测试时,都会导致“StopIteration”错误。这是完整的堆栈跟踪:
ERROR: test_dummy (comminquiry.tests.test_views.TestUserCanAskQuestion)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/c/Users/Alire/Projects/mm/mm-bpmui/src/comminquiry/tests/test_views.py", line 32, in test_dummy
a = ContactFactory.build()
File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/base.py", line 546, in build
return cls._generate(enums.BUILD_STRATEGY, kwargs)
File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/base.py", line 500, in _generate
return step.build()
File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/builder.py", line 272, in build
step.resolve(pre)
File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/builder.py", …Run Code Online (Sandbox Code Playgroud) 我需要使用factory boy. 我有以下模型:
class Fabric(models.Model):
title = models.CharField(max_length=200, blank=True)
description = models.CharField(max_length=200, blank=True)
price = models.DecimalField(decimal_places=2, max_digits=10, null=True, blank=False)
Run Code Online (Sandbox Code Playgroud)
我需要基于这个模型创建一个工厂,我希望价格在 1 到 100 之间有一个随机值。
class FabricFactory(DjangoModelFactory):
class Meta:
model = Fabric
title = factory.Faker('name')
description = factory.Faker('catch_phrase')
price = random.randrange(MIN_PRICE, MAX_PRICE + 1)
Run Code Online (Sandbox Code Playgroud)
问题在于我总是为每个实例获得相同的价格。
我正在使用 Django 3 和 Python 3.8。我有以下模型,请注意“类型”ManyToMany 字段,其中我将“空白”设置为 False。
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250, null=False)
types = models.ManyToManyField(CoopType, blank=False)
addresses = models.ManyToManyField(Address)
enabled = models.BooleanField(default=True, null=False)
phone = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_phone')
email = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_email')
web_site = models.TextField()
Run Code Online (Sandbox Code Playgroud)
我想验证如果将该字段留空会发生验证错误,所以我有
@pytest.mark.django_db
def test_coop_create_with_no_types(self):
""" Verify can't create coop if no """
coop = CoopFactory.create(types=[])
self.assertIsNotNone(coop)
self.assertNone( coop.id )
Run Code Online (Sandbox Code Playgroud)
并使用以下工厂(带有 FactoryBoy)来构建模型
class CoopFactory(factory.DjangoModelFactory):
"""
Define Coop Factory
"""
class Meta:
model = Coop
name = "test model" …Run Code Online (Sandbox Code Playgroud) django django-models django-validation python-3.x factory-boy
我有一个这样的工厂:
class PayInFactory(factory.DjangoModelFactory):
class Meta:
model = PayIn
@factory.lazy_attribute
def card(self):
if self.booking_payment and self.booking_payment.payment_type in [bkg_cts.PAYMENT_CARD, bkg_cts.PAYMENT_CARD_2X]:
factory.SubFactory(
CardFactory,
user=self.user,
)
Run Code Online (Sandbox Code Playgroud)
card仅当该booking_payment字段具有payment_type以下值时,我才尝试生成该字段[bkg_cts.PAYMENT_CARD, bkg_cts.PAYMENT_CARD_2X]
代码进入该语句,但生成后卡字段为空。
我怎样才能正确地做到这一点?允许SubFactory进入吗lazy_attribute?
如果可能的话,我希望能够从 PayInFactory 修改卡字段,如下所示:
>>> PayInFactory(card__user=some_user)
Run Code Online (Sandbox Code Playgroud)
PostGeneration不会这样做,因为我需要Card在调用创建之前使其可用。我覆盖了_create,它可能会使用该卡(如果可用)。
谢谢 !
我需要 SubFactory 的属性而不是它创建的对象。
# models.py
class User:
pass
class UserProfile:
user = models.OneToOneField(User)
class Job:
user = models.ForeignKey(User)
# factories.py
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
class UserProfileFactory(factory.django.DjangoModelFactory):
class Meta:
model = UserProfile
user = factory.SubFactory(UserFactory)
class JobFactory(factory.django.DjangoModelFactory):
class Meta:
model = Job
# for certain reasons, I want to use UserProfileFactory here but get the user generated from it
user = factory.SubFactory(UserProfileFactory).user # doesn't work but you get the idea
Run Code Online (Sandbox Code Playgroud) 我对factory-boy很陌生,我正在尝试向单元测试中的 API 端点发送请求,这需要对用户进行身份验证。端点需要在标头中以'Bearer ' + token. 我在网上查看了一些示例,这是我迄今为止在单元测试中提出的:
测试用户.py
class UserFactory(factory.Factory):
class Meta:
model = user
username = factory.LazyAttribute(lambda t: "myuser")
password = factory.PostGenerationMethodCall('set_password', 'my_super_secret')
is_staff = True
is_active = True
class UserViewSetTest(TestCase):
def setUp(self):
pwd = 'my_super_secret'
self.user = UserFactory(password=pwd)
self.client = Client()
self.assertTrue(self.client.login(username=self.user.username, password=pwd))
def test_user_list(self):
response = self.client.get(reverse('user', kwargs={'fromdate': '2017-01-01', 'todate': '2017-04-01'})), format='json')
self.assertEqual(response.status_code, 200)
Run Code Online (Sandbox Code Playgroud)
最初的错误是这个断言self.assertTrue(self.client.login(username=self.user.username, password=pwd))是错误的,因此测试立即失败。即使我删除了该行,API 调用也会返回 401,因为身份验证不成功。
如何使用 factory-boy 在此 API 调用中成功验证用户,以便我可以在 API 请求中发送令牌?我可以使用框架提供的用户模型吗?
编辑:
我试图创建一个令牌,以便将它传递给这样的标头:
def setUp(self): …Run Code Online (Sandbox Code Playgroud) django unit-testing django-unittest django-rest-framework factory-boy
我的模型的保存方法是在保存后调用 api。为了测试我的应用程序,我使用DjangoModelFactory生成用于测试的对象。但是,api仍然被调用。
class MyClass(models.Model):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.call_api()
Run Code Online (Sandbox Code Playgroud)
我尝试过模拟该方法,但它不起作用
#...
from .models import MyModel
@pytest.mark.django_db
@patch("MyModel.call_api")
class MyModelFactory(factory.django.DjangoModelFactory, factory.base.BaseFactory):
class Meta:
model = MyModel
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我将它与工厂一起使用时,如何使用模拟方法?