[英]Unit testing a Django query set
我正在尝试用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])
即使device.get_ips()
和[ip1, ip2, ip3]
的字符串表示相同,测试结果也会因为AssertionError
失败。
如果我尝试使用self.assertListEqual
我会收到一个错误,因为device.get_ips()
是一个QuerySet而不是一个列表。
如果我尝试self.assertQuerySetEqual
我得到一个错误说“ DeviceTest object has no attribute assertQuerySetEqual
”但我不知道为什么因为DeviceTest
扩展了django.test
的TestCase。
我该怎么做这样的测试?
此外,在“真实”项目中进行这样一个简单的测试是否有意义?
实际上正确的方式,并由djangoproject推荐是:
self.assertEqual(list(device.get_ips()), [ip1, ip2, ip3])
在查询集和列表上强制sorted
将改变您的测试场景,而您不希望它。
调用device.get_ips()
返回一个QuerySet
而[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)
这个测试:三个结果和IP是相同的。 这应该让您有理由相信您获得了相同的对象(尽管您可以根据需要添加更多断言)。
你键入self.assertQuerySetEqual
,它应该是self.assertQuerysetEqual
,尝试:
self.assertQuerysetEqual(device.get_ips(), [repr(ip1), repr(ip2), repr(ip3)],
ordered=False)
或者,如果您仍想针对列表进行测试:
self.assertItemsEqual(device.get_ips(), [ip1, ip2, ip3])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.