【问题标题】:IntegrityError in Django testcaseDjango 测试用例中的 IntegrityError
【发布时间】:2019-09-11 08:13:05
【问题描述】:

我怀疑transaction.atomic() 在测试期间没有将我的instance 提交到数据库。问题可能来自多个数据库

from django.db import models
from model_utils.models import TimeStampedModel


class PIIField(TimeStampedModel):
    """
    Personal Information Identifier configuration model
    This model is M2M on `Plan`
    """
    name = models.CharField(max_length=30)
    detail = models.CharField(max_length=50, null=True, blank=True)
    order = models.SmallIntegerField(unique=True)

    def __str__(self):
        return self.name

class Plan(timestamp.Model, models.Model):
    class Meta:
        db_table = "catalog_plans"

    product = models.ForeignKey(Product,
                                on_delete=models.CASCADE,
                                related_name="plans")
    coverages = models.ManyToManyField(Coverage, through="PlanCoverage")
    code = models.TextField(null=True)
    name = models.TextField()
    pii_fields = models.ManyToManyField(PIIField, related_name='plans', related_query_name='plan')

这是我的tests.py

from django.db import transaction
from django.test import TransactionTestCase
from model_mommy import mommy
from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APIClient

from catalog.models import Plan
from pii_fields.models import PIIField


class PIIFieldTestCase(TransactionTestCase):
    databases = {'default', 'product', 'customer'}

    def setUp(self) -> None:
        with transaction.atomic():
            self.plan = mommy.make(Plan, code='88', name='Non risky life') # single `plan` with no` pii_fields` attached
            self.field_1 = mommy.make(PIIField, name='first_name', detail='text box', order=1)
            self.field_2 = mommy.make(PIIField, name='last_name', detail='text box', order=2)
            self.field_3 = mommy.make(PIIField, name='weight', detail='real number', order=3)
            self.field_4 = mommy.make(PIIField, name='nationality', detail='drop down', order=4)
            self.plan.pii_fields.set([self.field_1, self.field_2, self.field_3, self.field_4])

    def test_get(self):
        """
        Get the endpoint and see the payload sample
        :return:
        """
        client = APIClient()
        url = reverse('api:pii_field-detail', args=[self.plan.id])
        res = client.get(url)
        self.assertEqual(status.HTTP_200_OK, res.status_code)

错误:

django.db.utils.IntegrityError: insert or update on table "catalog_plans_pii_fields" violates foreign key constraint "catalog_plans_pii_fi_piifield_id_58130345_fk_pii_field"
DETAIL:  Key (piifield_id)=(1) is not present in table "pii_fields_piifield".

问题:
如何测试我的数据库和视图集?

【问题讨论】:

  • 你为什么在这里使用transaction.atomic?
  • @DanielRoseman 因为我怀疑 IntegrityError 在运行测试时从未提交的事务中引发

标签: django python-3.x testing django-models multiple-databases


【解决方案1】:

我必须使用另一种语法来添加我的记录。我试过bulk_create,但它不起作用

self.plan.pii_fields.create(name='first_name', detail='text box', order=1)
self.plan.pii_fields.create(name='last_name', detail='text box', order=2)
self.plan.pii_fields.create(name='weight', detail='real number', order=3)
self.plan.pii_fields.create(name='nationality', detail='drop down', order=4)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 2013-11-20
    • 2014-12-13
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多