模拟的 class 函数应该被调用一次但是 call_count == 0?

mocked class function should be called once but call_count == 0?

我有以下mod1.py待测

_p = None

def get_p():
    global _p
    if _p is None:
        _p = P()
    return _p

def deco(f):
    p = get_p()
    def wrapper(*args, **kwargs):
        p.func1()
        return f(*args, **kwargs)
    return wrapper

P,

class P:
    def func1(self):
        pass

我有以下测试代码。

@mock.patch('mod1.get_p')
def test_1(mocked):
    mocked.get_p = mock.Mock(P) 

    @mod1.deco()
    def test():
        pass

    test() # will call _p.func1() once

    assert mocked.func1.call_count == 1 # func1.count_count is zero

然而,它失败了

>       assert p.func1.call_count == 1
E       AssertionError: assert 0 == 1

为什么 call_count 是 0?

为什么代码不起作用

通常,您会收到 0 次调用,因为您的装饰器不会调用 _p.func1

你不必写 mocked.get_p 因为你已经伪造了它,因此你的 mocked 参数代表 mod.get_p 函数。

此外,您不应重新定义 mocked 变量,因为它已经是 mock.Mock

的实例

mod1你有一个错误,你的deco装饰器是错误的,我建议你阅读更多关于python装饰器的内容。

适合您案例的工作代码

mod1.py

class P:
    def func1(self):
        pass


_p = None

def get_p():
    global _p
    if _p is None:
        _p = P()
    return _p

 # other code omitted, it's a decorator which will call _p.func1 once
def deco(func):
    def wrapper(*args, **kwargs):
        p = get_p()
        p.func1()
        return func(*args, **kwargs)
    return wrapper

test_mod1.py

import unittest
from unittest import mock

import mod1

class TestFunc1(unittest.TestCase):
    @mock.patch('mod1.get_p')
    def test_1(self, mocked):
        _p_mock = mock.Mock()
        mocked.return_value = _p_mock

        @mod1.deco
        def test():
            pass

        test()

        _p_mock.func1.assert_called_once()


if __name__ == '__main__':
    unittest.main()

运行 在 openSUSE 风滚草上,Python3.8.5:

> python test_mod1.py

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK