【问题标题】:FactoryBoy is accessing normal DB instead of TEST DBFactoryBoy 正在访问普通数据库而不是 TEST 数据库
【发布时间】:2021-10-25 21:11:15
【问题描述】:

我正在尝试在 Django 测试用例的 setUp 方法中创建一些对象。我使用FactoryBoy 来帮助我创建对象。但似乎FactoryBoy 在数据库中找不到任何对象。

factories.py

class ProductFactory(DjangoModelFactory):
    ...
    market_category = factory.fuzzy.FuzzyChoice(list(MarketplaceCategory.objects.all()))

    class Meta:
        model = Product

tests.py

from django.test import TestCase
from marketplaces.models import MarketplaceCategory

class MyTestCase(TestCase):

    def setUp(self) -> None:
        ...
        self.marketplace_category = MarketplaceCategoryFactory.create()
        print(MarketplaceCategory.objects.first().pk) # prints 1
        self.product = ProductFactory(created_by=self.user)

如您所见,ProductFactory 尝试通过随机 MarketCategory 对象填充 Product.market_category

问题在于,即使我之前创建过它并确保它在数据库中(它有pk),它似乎也不存在。

编辑:它选择了一个 pk=25 的 MarketCategory 对象,但测试数据库中只有一个 pk=1 的对象。我认为它访问的是 Django 开发数据库而不是测试数据库。

错误:

psycopg2.errors.ForeignKeyViolation: insert or update on table "products_product" violates foreign key constraint "products_product_market_category_id_2d634517_fk"
DETAIL:  Key (market_category_id)=(25) is not present in table "marketplaces_marketplacecategory".

你知道它为什么会这样吗?出于某种原因,Factory 似乎正在访问真实的 DB 而不是 testdb

【问题讨论】:

    标签: python django django-orm django-testing factory-boy


    【解决方案1】:

    像这样定义“market_category”字段会导致问题,每当导入模块并且返回的实例可能不再存在时,填充选项的查询集将在某个随机时间执行。你应该使用SubFactory

    class ProductFactory(DjangoModelFactory):
        
        market_category = factory.SubFactory(MarketplaceCategoryFactory)
    
        class Meta:
            model = Product
    

    将查询集直接传递给FuzzyChoice 以获取随机现有值,不要将其转换为列表

    class ProductFactory(DjangoModelFactory):
        
        market_category = factory.fuzzy.FuzzyChoice(MarketplaceCategory.objects.all())
    
        class Meta:
            model = Product
    

    这将在您创建产品时创建一个实例,但您可以将“market_category”传递给工厂以覆盖它

    class MyTestCase(TestCase):
    
        def setUp(self) -> None:
            self.marketplace_category = MarketplaceCategoryFactory.create()
            self.product = ProductFactory(created_by=self.user, market_category =self.marketplace_category)
    

    【讨论】:

    • 谢谢,但是如果我想选择一个随机对象怎么办?
    • @Milano 将查询集直接传递给 FuzzyChoice,不要将其转换为列表。上面的例子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2015-01-08
    • 2013-02-19
    • 2012-05-08
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多