首页 > 解决方案 > FactoryBoy 正在访问普通数据库而不是 TEST 数据库

问题描述

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

工厂.py

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

    class Meta:
        model = Product

测试.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尝试Product.market_category通过随机MarketCategory对象填充。

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

编辑:它选择了一个MarketCategorypk=25 的对象,但在 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出于某种原因。

标签: pythondjangodjango-ormdjango-testingfactory-boy

解决方案


像这样定义“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)

推荐阅读