为什么 unittest.mock.ANY 不能正确处理 Django 对象?

Why doesn't unittest.mock.ANY work correctly with Django objects?

我用 Django 写了一个测试,我 。这是测试:

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 在这种情况下不起作用?它似乎适用于字符串和数字。

assertEqual,在比较其两个参数的过程中,计算表达式 user == mock.ANY。在标准方式中,left 参数确定哪个函数实际实现 ==。在这种情况下,您有 user.__eq__(mock.ANY)。看起来无论 user 是什么类型,它的 __eq__ 方法只是 returns False 用于意外类型。如果它改为引发 NotImplemented,该语言将退回到 mock.ANY.__eq__(user),这可能 return True.

如果您将调用更改为

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

那么结果比较 mock.ANY == user 将 return True 如预期的那样。