为什么unittest.mock.ANY无法正确使用Django对象?

时间:2019-08-23 13:35:34

标签: python django python-unittest django-testing

我已经用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为什么不起作用?似乎可以使用字符串和数字。

1 个答案:

答案 0 :(得分:2)

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