我正在尝试使用django 2.2.4/sqlite3 2.6.0/python 3.6.8测试一些简单的抽象mixin。
目前,我在使用模式编辑器从测试数据库中删除模型时遇到了问题。
我有以下测试用例:
from django.test import TestCase
from django.db.models.base import ModelBase
from django.db import connection
class ModelMixinTestCase(TestCase):
"""
Test Case for abstract mixin models.
"""
mixin = None
model = None
@classmethod
def setUpClass(cls) -> None:
# Create a real model from the mixin
cls.model = ModelBase(
"__Test" + cls.mixin.__name__,
(cls.mixin,),
{'__module__': cls.mixin.__module__}
)
# Use schema_editor to create schema
with connection.schema_editor() as editor:
editor.create_model(cls.model)
super().setUpClass()
@classmethod
def tearDownClass(cls) -> None:
# Use schema_editor to delete schema
with connection.schema_editor() as editor:
editor.delete_model(cls.model)
super().tearDownClass()
可以这样使用:
class MyMixinTestCase(ModelMixinTestCase):
mixin = MyMixin
def test_true(self):
self.assertTrue(True)
这允许创建和测试模型。问题是在ModelMixinTestCase.tearDownClass
中,connection.schema_editor()
无法禁用django.db.backends.sqlite3.base
中使用的约束检查:
def disable_constraint_checking(self):
with self.cursor() as cursor:
cursor.execute('PRAGMA foreign_keys = OFF')
# Foreign key constraints cannot be turned off while in a multi-
# statement transaction. Fetch the current state of the pragma
# to determine if constraints are effectively disabled.
enabled = cursor.execute('PRAGMA foreign_keys').fetchone()[0]
return not bool(enabled)
这导致django.db.backends.sqlite3.schema
中的DatabaseSchemaEditor
在__enter__
中出现异常:
def __enter__(self):
# Some SQLite schema alterations need foreign key constraints to be
# disabled. Enforce it here for the duration of the schema edition.
if not self.connection.disable_constraint_checking():
raise NotSupportedError(
'SQLite schema editor cannot be used while foreign key '
'constraint checks are enabled. Make sure to disable them '
'before entering a transaction.atomic() context because '
'SQLite does not support disabling them in the middle of '
'a multi-statement transaction.'
)
return super().__enter__()
因此,基于所有这些,我假设我们处于原子上下文中,但我目前不确定退出该上下文并删除模型的最干净方法是什么。
2条答案
按热度按时间eufgjt7s1#
简单解决方案
因此,经过一点挖掘和测试,似乎最好让django的
TestCase
正常关闭事务,然后从测试数据库中删除模型。基本上,我们只是先调用super().tearDownClass()
而不是last。ModelMixinTestCase
因为这是一个有用的类,我将发布完整的类供其他人复制/粘贴。
示例用法1
示例用法二
s2j5cfk02#
@bob谢谢你的好办法,效果很好。
但是当在具有相同模型的不同TestCase上重用mixin时,我遇到了一个警告:
我通过检查模型是否已经在应用程序中注册来解决这个问题: