Django模型测试中未解决的错误

时间:2018-07-19 13:42:26

标签: django django-testing

from django.test import TestCase
from .models import Publisher

class PublisherModelTestCase(TestCase):
    def setUp(self):
        Publisher.objects.create(name = 'some random test title',website = 'cn@gmail.com')

    def test_publisher_title(self):
        obj = Publisher.objects.get(website = 'cn@gmail.com')
        self.assertEqual(obj.name,'some random test title')

    def test_str_representation(self):
        obj = Publisher.objects.get(name='some random test titile')
        self.assertEqual(obj,obj.__str__())

我已经为我的模型创建了这个测试用例,但是尽管在python shell中工作,但是当我运行上述代码时它显示了错误。请纠正我在哪里做错了。

models.py

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField(blank=True)

    class Meta:
        ordering = ["-name"]

    def __str__(self):
        return self.name

说我通过setUp函数创建的对象不存在。但是在python shell中,它使用相同的值创建对象。

ERROR: test_publisher_title (cbv.tests.PublisherModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\django\blog_env\mysite\cbv\tests.py", line 13, in test_publisher_title
    obj = Publisher.objects.get(website = 'cn@gmail.com')
  File "D:\django\blog_env\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\django\blog_env\lib\site-packages\django\db\models\query.py", line 403, in get
    self.model._meta.object_name
cbv.models.DoesNotExist: Publisher matching query does not exist.

======================================================================
ERROR: test_str_representation (cbv.tests.PublisherModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\django\blog_env\mysite\cbv\tests.py", line 17, in test_str_representation
    obj = Publisher.objects.get(name='some random test titile')
  File "D:\django\blog_env\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\django\blog_env\lib\site-packages\django\db\models\query.py", line 403, in get
    self.model._meta.object_name
cbv.models.DoesNotExist: Publisher matching query does not exist.

----------------------------------------------------------------------
Ran 4 tests in 0.595s

FAILED (errors=2)

因此,我将get()更改为filter(),并将查询更正为'....title',但是现在出现了新错误。

ERROR: test_publisher_title (cbv.tests.PublisherModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\django\blog_env\mysite\cbv\tests.py", line 14, in test_publisher_title
    self.assertEqual(obj.name,'some random test title')
AttributeError: 'QuerySet' object has no attribute 'name'

======================================================================
ERROR: test_str_representation (cbv.tests.PublisherModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\django\blog_env\mysite\cbv\tests.py", line 18, in test_str_representation
    self.assertEqual(obj.name,obj.__str__())
AttributeError: 'QuerySet' object has no attribute 'name'

----------------------------------------------------------------------
Ran 4 tests in 0.152s

FAILED (errors=2)

2 个答案:

答案 0 :(得分:0)

此错误是因为使用.get()的查询为空。如果查询为空或包含多个结果,.get()将返回错误。在适当条件下使用.filter()

请参见doc

.get()直接返回一个对象时,filter()返回一个查询集,因此您必须检查查询集是否为空,然后使用queryset.first()queryset[0]

另一种解决方案是将.get()包装在try / except块中:

try:
    obj = Publisher.objects.get(website = 'cn@gmail.com')
except:
    # No Publisher was found for this website
    # Do something

答案 1 :(得分:0)

更改

obj = Publisher.objects.get(name='some random test titile')

obj = Publisher.objects.get(name='some random test title')