微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Django 单元测试因唯一约束而失败

如何解决Django 单元测试因唯一约束而失败

我正在编写一个测试来验证字段的唯一性。在这个测试中,我试图验证产品的 slug 是唯一的。我最初的测试如下:

from django.test import TestCase
from django.urls import reverse
from django.forms import ValidationError
from django.db.utils import IntegrityError
from rest_framework.test import apiclient
from rest_framework import status

from .factories import ProductFactory
from .models import Product
from .serializer import ProductSerializer

PRODUCTS_URL = reverse('product-list')

def create_product(**params):
    """ Helper function to create a new product """
    return Product.objects.create(**params)

class PrivateProductsTests(TestCase):

    def setUp(self):
        self.client = apiclient()
    
    
    def test_an_error_occurs_when_forcing_the_same_slug_for_different_products(self):

        product1 = ProductFactory.create(slug='')
        serializer1 = ProductSerializer(product1)
        product1_data = serializer1.data

        product1 = create_product(**product1_data)

        product2 = ProductFactory.create(slug=product1.slug)
        serializer2 = ProductSerializer(product2)
        product2_data = serializer2.data

        self.assertRaises(IntegrityError,create_product(**product2_data))

但它失败并出现以下错误

django.db.utils.IntegrityError:重复键值违反唯一 约束“products_product_slug_key”细节:键 (slug)=(james-maxwell) 已经存在。

环顾四周,我发现以下问题提供了答案:

Fail on Testing IntegrityError UNIQUE constraint

现在我的测试看起来像:

def test_an_error_occurs_when_forcing_the_same_slug_for_different_products(self):

    product1 = ProductFactory.create(slug='')
    serializer1 = ProductSerializer(product1)
    product1_data = serializer1.data

    product1 = create_product(**product1_data)

    product2 = ProductFactory.create(slug=product1.slug)
    serializer2 = ProductSerializer(product2)
    product2_data = serializer2.data

    # there are two kinds of IntegrityError classes at play here,one
    # that's imported from the test and one raised by the db
    with self.assertRaises(IntegrityError) as raised:
        product2 = create_product(**product2_data)
    
    # print(type(raised.exception))
    self.assertEqual(IntegrityError,type(raised.exception))

但我想更进一步检查系统中没有存储任何内容,因此我将测试修改为(检查最后两行):

def test_an_error_occurs_when_forcing_the_same_slug_for_different_products(self):

product1 = ProductFactory.create(slug='')
serializer1 = ProductSerializer(product1)
product1_data = serializer1.data

product1 = create_product(**product1_data)

product2 = ProductFactory.create(slug=product1.slug)
serializer2 = ProductSerializer(product2)
product2_data = serializer2.data
print(product1.slug)
print(product2_data)

# self.assertRaises(IntegrityError,create_product(**product2_data))

# there are two kinds of IntegrityError classes at play here,one
# that's imported from the test and one raised by the db
with self.assertRaises(IntegrityError) as raised:
    product2 = create_product(**product2_data)

# print(type(raised.exception))
self.assertEqual(IntegrityError,type(raised.exception))

# verify there's only one item in the db
res = self.client.get(PRODUCTS_URL)
print(res.data)

添加这两行后,我收到以下错误

“当前事务发生错误。您不能” django.db.transaction.TransactionManagementError:发生错误 当前交易。直到结束时您才能执行查询 “原子”块。

我该如何解决这个问题?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。