首页 > 解决方案 > 如何模拟就地算术运算符

问题描述

我试图__iadd__MagicMockfrom模拟就地操作员的魔术方法unittest.mock,但调用断言意外失败:

>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m += 1
>>> m.__iadd__.assert_called_once()  # This expected NOT to fail
Traceback (most recent call last):
  ...
AssertionError: Expected '__iadd__' to have been called once. Called 0 times.

模拟其他魔术方法效果很好:

>>> m = MagicMock()
>>> m + 1
>>> m.__add__.assert_called_once()
>>> # No error

在对新实例进行m += 1设置之后,因为所有模拟方法都返回新的模拟。我们像这样在常规类中覆盖:mMagicMock__iadd__

class A:
    def __iadd__(self, other):
        ...
        return self  # <-- We must return self

但是所有模拟的方法包括__iadd__看起来像:

def __iadd__(self, *args, **kwargs):
    ...
    return MagicMock()

在我看来,这就是它失败的原因。


那么,我如何正确地模拟就地算术魔术方法呢?

标签: pythonmocking

解决方案


像这样更改返回值__iadd__

>>> m = MagicMock()
>>> m.__iadd__.return_value = m
>>> m += 1
>>> m.__iadd__.assert_called_once()
>>> m.__iadd__.call_count
1

推荐阅读