Django 单元测试:应该如何测试抽象模型?

Django unit testing: How should one test abstract models?

在我的 Django 项目中,我有一个名为 'core' 的应用程序,其中包含我所有的可重用模型混合/抽象模型 (behaviors.py)、模型 (models.py)、视图 (views.py) 和辅助函数 (utils.py):

core/
    __init__.py
    behaviors.py  
    models.py
    utils.py
    views.py

我现在想为这些文件编写测试。对于模型、实用程序和视图,我只是像以前一样编写单元测试。

我现在不确定应该如何测试 behaviors.py 中包含的抽象模型。例如,我有这个模型混合:

import uuid as uuid_lib

from django.db import models


class UniversallyUniqueIdentifiable(models.Model):
    uuid = models.UUIDField(
    db_index=True,
    default=uuid_lib.uuid4,
    editable=False
        )

    class Meta:
        abstract = True

如何测试抽象模型? 在one of the articles我以前学过胖模型,作者只是测试他使用抽象模型的模型。但这对我来说感觉不是很干,因为这意味着我必须在我使用它的每个模型中测试 UUID 的添加。 有更好的方法吗?

试试下面的代码

from django.db import connection
from django.db.models.base import ModelBase
from django.test import TestCase
from .models import UniversallyUniqueIdentifiable

import uuid    


class TestUniversallyUniqueIdentifiable(TestCase):

    model = UniversallyUniqueIdentifiable

    def setUp(self):
        # Create a dummy model
        self.model = ModelBase(
            '__TestModel__' + self.model.__name__, (self.model,),
            {'__module__': self.model.__module__}
        )

        # Create the schema for our test model
        with connection.schema_editor() as schema_editor:
            schema_editor.create_model(self.model)

    def test_mytest_case(self):

        self.model.objects.create(uuid=uuid.uuid4())
        self.assertEqual(self.model.objects.count(), 1) 

    def tearDown(self):
        # Delete the schema for the test model
        with connection.schema_editor() as schema_editor:
            schema_editor.delete_model(self.model)

Anjaneyulu Batta 的答案令人惊叹,但可读性不强,如果 Django 团队改变 connection 内部行为方式,则可能难以维护。

我会做什么:

  1. 测试抽象class'通用属性任何使用这个抽象class的模型。
  2. 测试此 是 class 的子class 摘要 class。
  3. 测试此模型的特定属性
  4. 对任何其他模型重复 2 和 3。

示例:一个摘要 class Parallelogram 和一个使用它的模型称为 Square .

from unittest import TestCase

from tetrahedrons.models import Parallelogram, Square

class ParallelogramAbstractModelTest(TestCase):
    def test_has_four_sides(self):
        ...

    def test_parallel_opposite_sides(self):
        ...

class SquareModelTest(TestCase):
    def test_subclasses_mobel_base(self):
        self.assertTrue(issubclass(Square, Parallelogram))

    def test_equal_sides(self):
        ...