Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 单元测试Django查询集_Python_Django_Django Unittest_Python Unittest - Fatal编程技术网

Python 单元测试Django查询集

Python 单元测试Django查询集,python,django,django-unittest,python-unittest,Python,Django,Django Unittest,Python Unittest,我正在尝试使用Django/unittest学习单元测试 以下是我的模型的简单版本: class Device(models.Model): name = models.CharField(max_length=100) def get_ips(self): return DeviceIP.objects.filter(device=self.id) class DeviceIP(models.Model): ip = models.GenericI

我正在尝试使用Django/unittest学习单元测试

以下是我的模型的简单版本:

class Device(models.Model):
    name = models.CharField(max_length=100)

    def get_ips(self):
        return DeviceIP.objects.filter(device=self.id)


class DeviceIP(models.Model):
    ip = models.GenericIPAddressField()
    device = models.ForeignKey(Device)
这是我想出的测试代码:

from django.test import TestCase

class DeviceTest(TestCase):

    def test_get_ips(self):
        device = Device()
        device.name = 'My Device'

        ip1 = DeviceIP()
        ip1.ip = '127.0.0.1'
        ip1.device = device
        ip1.save()

        ip2 = DeviceIP()
        ip2.ip = '127.0.0.2'
        ip2.device = device
        ip2.save()

        ip3 = DeviceIP()
        ip3.ip = '127.0.0.3'
        ip3.device = device
        ip3.save()

        self.assertEqual(device.get_ips(), [ip1, ip2, ip3])
测试结果失败,因为在
断言错误上
,即使
设备.get_ips()
[ip1、ip2、ip3]
的字符串表示形式相同

如果我尝试使用
self.assertListEqual
我会得到一个错误,因为
device.get\u ips()
是一个查询集,而不是列表

如果我尝试
self.assertquerystequal
我会得到一个错误,说“
DeviceTest对象没有属性assertquerystequal
”,但我不确定为什么,因为
DeviceTest
扩展了
django.test
的测试用例

我应该怎么做这样的测试


另外,在一个“真正”的项目中,做这样一个简单的测试有意义吗?

调用
设备。get_ips()
返回一个
查询集,而
[ip1,ip2,ip3]
是一个列表。因此,他们目前并不平等

考虑到您不想测试可能无关紧要的内容(从数据库返回
.filter()
中的行的顺序),我建议按如下方式进行测试:

results = device.get_ips()
result_ips = [ip.ip for ip in results]
self.assertEqual(len(results), 3)
self.assertTrue(ip1.ip in result_ips)
self.assertTrue(ip2.ip in result_ips)
self.assertTrue(ip3.ip in result_ips)

此测试:三个结果和IPs相同。这应该可以让您合理地确信您得到的是相同的对象(尽管您可以根据需要添加更多断言)。

实际上正确的方法,djangoproject建议:

    self.assertEqual(list(device.get_ips()), [ip1, ip2, ip3])

在queryset和list上强制执行
sorted
,将更改您的测试场景,您不需要它。

您键入了
self.AssertQuerySequal
,它应该是
self.AssertQuerySequal
,请尝试:

self.assertQuerysetEqual(device.get_ips(), [repr(ip1), repr(ip2), repr(ip3)], 
                         ordered=False)
或者,如果您仍要根据列表对其进行测试:

self.assertItemsEqual(device.get_ips(), [ip1, ip2, ip3])

您是否知道,使用
device.deviceip\u set.all()
是Django的内置方法,可以完成您的
get\u ips()
方法的功能?查看Django的文档以了解反向外键。你也不需要测试它,因为它是标准的Django行为。谢谢@Ben,我才刚刚开始学习Django,还没有意识到这一点。我将切换到使用这种方法。或者,由于输入是唯一的,只需在断言中应用排序,它将同时考虑列表长度和内容
self.assertEqual(已排序(result_-ips),已排序([ip1,ip,ip2.ip,ip3.ip])
感谢您的回答和评论,这两个答案都对我有用。我将改为使用Ben在上面推荐的
deviceip_set()
,但这正是我了解如何进行此类测试所需要的@AustinPhillips,轻微打字错误:
ip1,ip
应该是
ip1.ip