python - 重用Mock创建属性模拟unittest.patch

标签 python unit-testing mocking python-unittest

from unittest.mock import patch


class A:
    def b(self):
        return 'HAHAHA A'
a = A()

with patch('__main__.A') as a_mock:
    a_mock.b.return_value = 'not working'
    print(a.b())

HAHAHA A
>>>

为什么它不打印'notworking'?那么 a_mock 是做什么用的呢? ______________

最佳答案

您用补丁替换了整个类,而不是现有类上的方法。 a = A() 在替换类之前创建了 A 的实例,因此 a.__class__ 仍然引用实际类,而不是模拟类.

模拟一次只能替换一个引用,而不能替换所引用的对象。在补丁之前,名称 A 和属性 a.__class__ 都是对类对象的引用。然后,您仅修补 A 引用,将 a.__class__ 保留在原处。

换句话说,a.__class__ 没有被修补,只有 AA().b() 打印不工作

您必须仅仅修补类上的方法,以便a.__class__仍然引用A,并且 a.b 将解析为修补后的 A.b 模拟:

with patch('__main__.A.b') as b_mock:
    b_mock.return_value = 'working as long as you patch the right object'
    print(a.b())

演示:

>>> with patch('__main__.A.b') as b_mock:
...     b_mock.return_value = 'working as long as you patch the right object'
...     print(a.b())
...
working as long as you patch the right object

不幸的是,你不能用Mock来修补a.__class__引用; Python 只允许您使用该属性的实际类。

>>> with patch('__main__.a.__class__') as a_class_mock:
...     a_class_mock.b.return_value = 'working as long as you patch the right object'
...     print(a.b())
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.5/unittest/mock.py", line 1312, in __enter__
    setattr(self.target, self.attribute, new_attr)
TypeError: __class__ must be set to a class, not 'MagicMock' object

关于python - 重用Mock创建属性模拟unittest.patch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39449844/

相关文章:

java - 如何在 Java 中创建接口(interface)的代理?

ios - 如何在 Swift 4 中测试 API?

javascript - 何时使用 Microsoft 报告服务

python - python 多处理函数返回多个输出

Python:有没有办法强制父函数返回?

c# - 如何使用 MOQ 框架在 c# 中模拟静态方法?

java - java Mock 文件的建议(模拟 java.io.File)

Python、单元测试、mock内置/扩展类型类方法

python - 如何使用 Selenium 从 devtools Network 面板中检索 "Initiator"字段?

python - 编写Python或TCL VMD脚本