如何在 Python 中模拟装饰器的内部调用

Posted

技术标签:

【中文标题】如何在 Python 中模拟装饰器的内部调用【英文标题】:How to mock an inner most call of a decorator in Python 【发布时间】:2016-01-06 10:39:57 【问题描述】:

我正在为我的包编写一些单元测试。假设我有以下文件:

包/a.py 包/测试/test_a.py

在 a.py 中,我有类:

class A:

    def m(x):
        def n(y):
            def o(self, z):
                pass # Parsing z
                if len(z) == x:
                    y(self, z)
            return o
        return n

在 test_a.py 中,我使用了from package import a 指令。作为此单元测试的一部分,我想知道 y 是否被调用但不调用 y(模拟此调用)。

我该如何进行这种模拟?

【问题讨论】:

【参考方案1】:

只需将模拟对象作为y 传递:

from unittest.mock import MagicMock

decorator = A.m(1)
y_mock = MagicMock()
decorated = decorator(y_mock)

self_mock = MagicMock()
decorated(self_mock, ['foo'])

y_mock.assert_called_with(self_mock, ['foo'])

上面通过调用A.m()创建了一个装饰器,将装饰器应用于y_mock对象,产生一个装饰的“函数”,就像你在def函数定义语句之前使用了@A.m(1)行一样。

然后我为装饰器创建 2 个参数,这样您就可以轻松测试 y_mock 是否被正确调用。

【讨论】:

以上是关于如何在 Python 中模拟装饰器的内部调用的主要内容,如果未能解决你的问题,请参考以下文章

浅谈对python装饰器的理解

python 多个装饰器的调用顺序

python闭包和装饰器的理解

Python闭包和装饰器

Python装饰器的实现和万能装饰器

如何在具有模拟装饰器的测试中使用 pytest capsys?