繁体   English   中英

单元测试Django查询集

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM