【问题标题】:Django: assertEquals with visually equal result with QuerySetDjango:assertEquals 与 QuerySet 具有视觉上相等的结果
【发布时间】:2020-05-24 13:27:29
【问题描述】:

谁能解释一下为什么它们具有相同的值,但不比较相等?有点难以理解。让它们“平等”的最佳方式是什么?

使用 ipdb 进行检查:

ipdb> expected_value                                                                                                                                  
{'author': 'john', 'id': 1, 'title': 'Yesterday', 'body': 'All my troubles seemed so far away', 'tags': <QuerySet ['Music', 'Lyrics']>}
ipdb> response                                                                                                                                        
{'author': 'john', 'id': 1, 'title': 'Yesterday', 'body': 'All my troubles seemed so far away', 'tags': <QuerySet ['Music', 'Lyrics']>}

代码片段:

class TestPost(TestCase):                                                                                               

    def test_serialize(self):                                                                                           
        user = User.objects.create(username="john", password="12345678", email="john@exemplo.com")                      
        tag1 = Tag.objects.create(value="Music")                                                                        
        tag2 = Tag.objects.create(value="Lyrics")                                                                       
        post = Post.objects.create(author=user, title="Yesterday", body="All my troubles seemed so far away")           
        post.tags.add(tag1)                                                                                             
        post.tags.add(tag2)                                                                                             

        expected_value = {                                                                                              
            "author": user.username,                                                                                    
            "id": user.id,                                                                                              
            "title": post.title,                                                                                        
            "body": post.body,                                                                                          
            "tags": post.tags.all().values_list("value", flat=True),                                                    
        }                                                                                                               
        response = post.serialize()                                                                                                                                      
        self.assertEqual(expected_value, response)

以及我正在测试的 Django 模型

class Post(models.Model):                                                                                               
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=False, null=False,)            
    title = models.CharField(blank=False, null=False, validators=[MinLengthValidator(3)], max_length=50)                
    body = models.CharField(blank=False, null=False, validators=[MinLengthValidator(5)], max_length=1000)               
    tags = models.ManyToManyField("Tag")                                                                                

    def serialize(self):                                                                                                
        return {                                                                                                        
            "author": self.author.username,                                                                             
            "id": self.id,                                                                                              
            "title": self.title,                                                                                        
            "body": self.body,                                                                                          
            "tags": self.tags.all().values_list("value", flat=True),                                                    
        } 

【问题讨论】:

  • 查询集不相等,甚至不等于具有相同值的查询集。

标签: python django testing automated-tests comparison


【解决方案1】:

谁能解释一下为什么它们具有相同的值,但不比较相等?

因为两个QuerySet objects [GitHub] 在“携带”相同的值时不被认为是相等的。只有当对象本身相同时,才会被认为是相等的。事实上,如果你在 shell 中测试它,你会检索到:

>>> MyModel.objects.all() == MyModel.objects.all()
False
>>> qs = MyModel.objects.all()
>>> qs == qs
True

毕竟QuerySet不仅是一个值的集合,还是一个查询,检查两个查询是否等价,大概就是一个undeciable problem [wiki]

因此,您可以使用list(…) 将其转换为列表,例如:

expected_value = {
    'author': user.username,
    'id': user.id,
    'title': post.title,
    'body': post.body,
    'tags': list(post.tags.values_list('value', flat=True)),
}

以及在序列化程序中:

class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(validators=[MinLengthValidator(3)], max_length=50)
    body = models.CharField(validators=[MinLengthValidator(5)], max_length=1000)
    tags = models.ManyToManyField("Tag")

    def serialize(self):
        return {
            'author': self.author.username,
            'id': self.id,
            'title': self.title,
            'body': self.body,
            'tags': list(self.tags.values_list('value', flat=True))
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多