【发布时间】:2020-08-11 09:05:49
【问题描述】:
我正在使用 Django 2 并尝试为我的模型编写一些单元测试。我有这些模型...
class CoopTypeManager(models.Manager):
def get_by_natural_key(self, name):
return self.get_or_create(name=name)[0]
class CoopType(models.Model):
name = models.CharField(max_length=200, null=False, unique=True)
objects = CoopTypeManager()
class CoopManager(models.Manager):
# Look up by coop type
def get_by_type(self, type):
qset = Coop.objects.filter(type__name=type,
enabled=True)
return qset
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250, null=False)
types = models.ManyToManyField(CoopType)
address = AddressField(on_delete=models.CASCADE)
enabled = models.BooleanField(default=True, null=False)
phone = PhoneNumberField(null=True)
email = models.EmailField(null=True)
web_site = models.TextField()
我创建了以下工厂来自动生成这些模型...
import factory
from .models import CoopType, Coop
class CoopTypeFactory(factory.DjangoModelFactory):
"""
Define Coop Type Factory
"""
class Meta:
model = CoopType
class CoopFactory(factory.DjangoModelFactory):
"""
Define Coop Factory
"""
class Meta:
model = Coop
coop_type = factory.SubFactory(CoopTypeFactory)
然后我创建了这个简单的测试......
import pytest
from django.test import TestCase
from .tests.factories import CoopTypeFactory, CoopFactory
class ModelTests(TestCase):
@classmethod
def setUpTestData(cls):
print("setUpTestData: Run once to set up non-modified data for all class methods.")
pass
def setUp(self):
print("setUp: Run once for every test method to setup clean data.")
pass
@pytest.mark.django_db
def test_coop_type_model():
""" Test coop type model """
# create coop type model instance
coop_type = CoopTypeFactory(name="Test Coop Type Name")
assert coop_type.name == "Test Coop Type Name"
但是当我运行测试时,我得到一个错误,“AttributeError: 'NoneType' object has no attribute '_meta'”
(venv) localhost:web davea$ python manage.py test
Creating test database for alias 'default'...
Got an error creating the test database: (1007, "Can't create database 'test_maps_data'; database exists")
Type 'yes' if you would like to try deleting the test database 'test_maps_data', or 'no' to cancel: yes
Destroying old test database for alias 'default'...
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/commands/test.py", line 26, in run_from_argv
super().run_from_argv(argv)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/base.py", line 335, in execute
output = self.handle(*args, **options)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/management/commands/test.py", line 59, in handle
failures = test_runner.run_tests(test_labels)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/test/runner.py", line 601, in run_tests
old_config = self.setup_databases()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/test/runner.py", line 548, in setup_databases
self.parallel, **kwargs
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/test/utils.py", line 176, in setup_databases
serialize=connection.settings_dict.get('TEST', {}).get('SERIALIZE', True),
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/base/creation.py", line 76, in create_test_db
self.connection._test_serialized_contents = self.serialize_db_to_string()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/base/creation.py", line 119, in serialize_db_to_string
serializers.serialize("json", get_objects(), indent=None, stream=out)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/serializers/__init__.py", line 128, in serialize
s.serialize(queryset, **options)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/core/serializers/base.py", line 80, in serialize
for count, obj in enumerate(queryset, start=1):
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/base/creation.py", line 116, in get_objects
yield from queryset.iterator()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 336, in _iterator
yield from self._iterable_class(self, chunked_fetch=use_chunked_fetch, chunk_size=chunk_size)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 54, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1050, in execute_sql
sql, params = self.as_sql()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 445, in as_sql
extra_select, order_by, group_by = self.pre_sql_setup()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 50, in pre_sql_setup
self.setup_query()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 40, in setup_query
self.query.get_initial_alias()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 886, in get_initial_alias
alias = self.join(BaseTable(self.get_meta().db_table, None))
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 284, in get_meta
return self.model._meta
AttributeError: 'NoneType' object has no attribute '_meta'
编辑:如果您想尝试重现问题,这里是一个 github 链接。项目在“网络”——https://github.com/chicommons/maps
【问题讨论】:
-
我试图重现该问题,但测试对我来说是无缝运行的 (screenshot)。我认为这个问题可能特定于您的环境。
-
您的问题可能来自迁移,您确定它们是最新的吗?
-
@SebCorbin ,当我运行“python manage.py makemigrations”时,我得到“未检测到更改”。当我运行“python manage.py migrate maps”时,我得到“No migrations to apply”。
-
@ArakkalAbu,我将 GitHub 项目链接作为对我问题的编辑。如果您有时间,我很想看看您是否能够重现该问题。
-
@Dave 尝试在新的数据库上运行您的迁移,如果您在执行此操作时遇到错误,则可以缩小问题范围
标签: django unit-testing django-models factory