【问题标题】:Why doesn't unittest.mock.ANY work correctly with Django objects?为什么 unittest.mock.ANY 不能与 Django 对象一起正常工作?
【发布时间】:2019-08-23 13:35:34
【问题描述】:

我在 Django 中编写了一个测试,我是 using unittest.mock.ANY to ignore certain values in a dictionary。这是测试:

from django.test import TestCase
from django.contrib.auth import get_user_model
import unittest.mock as mock

class Example(TestCase):
    def test_example(self):
        user = get_user_model().objects.create_user(username='example')
        result = {'user': user, 'number': 42}
        self.assertEqual(
            result,
            {'user': mock.ANY, 'number': 42}
        )

如果我运行这个测试,我希望它通过。相反,我得到了这个失败:

======================================================================
FAIL: test_example (example.tests.Example)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "example/tests.py", line 18, in test_example
    'number': 42,
AssertionError: {'user': <User: example>, 'number': 42} != {'user': <ANY>, 'number': 42}
- {'number': 42, 'user': <User: example>}
?                         ^^^^^^^^^^^^^

+ {'number': 42, 'user': <ANY>}
?                         ^^^

为什么ANY 在这种情况下不起作用?它似乎适用于字符串和数字。

【问题讨论】:

  • 如果换一种方式比较呢:self.assertEqual({'user': mock.ANY, 'number': 42}, result)?
  • assertEqual 正在尝试评估user == mock.ANY,它被实现为user.__eq__(mock.ANY),而不是mock.ANY.__eq__(user)。 type(user).__eq__ 似乎返回 False 而不是提升 NotImplemented,这将允许尝试 mock.ANY.__eq__。
  • 按照 Goyo 的建议,翻转订单将允许首先尝试 mock.ANY.__eq__。
  • @chepner 听起来像是一个答案!

标签: python django python-unittest django-testing


【解决方案1】:

assertEqual,在比较它的两个参数的过程中,计算表达式user == mock.ANY。在标准方式中,left 参数决定了哪个函数实际实现了==。在这种情况下,您拥有user.__eq__(mock.ANY)。似乎无论user 是什么类型,它的__eq__ 方法都会简单地为意外类型返回False。如果它改为引发NotImplemented,则该语言将退回到mock.ANY.__eq__(user),这可能会返回True。

如果你把调用改为

self.assertEqual(
            {'user': mock.ANY, 'number': 42},
            result,
        )

那么结果比较 mock.ANY == user 将按预期返回 True。

【讨论】:

  • 谢谢! Python 的文档通常会指明预期的结果是第二个参数,而要测试的参数是第一个参数,像这样:self.assertEqual(got, expected)。但我想assertEqual 如果这些参数的顺序颠倒了也同样有效。
猜你喜欢
  • 2021-08-18
  • 2021-12-06
  • 2020-09-01
  • 2012-08-17
  • 2021-12-15
  • 2011-10-05
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多