【问题标题】:How to Mock Instance Method in Python如何在 Python 中模拟实例方法
【发布时间】:2020-06-17 17:35:07
【问题描述】:

考虑以下三个文件。

# my_class.py

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5


# main.py

from my_class import MyClass

def my_func():
    instance = MyClass()
    instance.do_thing()


# test_main.py

from main import my_func
from unittest.mock import patch

@patch('main.MyClass')
def test_my_func(MockMyClass):
    my_func()
    MockMyClass.do_thing.assert_called_once()

AssertionError: Expected 'do_thing' to have been called once. Called 0 times.

我在驱动函数my_func 中实例化一个类MyClass 并调用该类的方法之一do_thing。我想做的是测试当驱动函数被调用时,类的方法被调用一次。我遇到了一个给我带来问题的断言错误。

我已经在线阅读了一百万零一篇关于 Python 模拟的 SO 帖子和其他资源,但我无法弄清楚这一点。我认为诀窍是 @patch 装饰器修补模块导入的命名空间,而不是来自 [Python Mocking a function from an imported module.我在这里做错了什么?

【问题讨论】:

  • my_func 创建一个 MyClass 实例并在该实例上调用 do_thing。您检查的是类,而不是实例。

标签: python mocking pytest python-unittest


【解决方案1】:

do_thing方法是MyClass的实例方法,NOT类方法。您断言MockMyClass.do_thing.assert_called_once() 不正确。这是单元测试解决方案:

my_class.py:

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5

main.py:


from my_class import MyClass


def my_func():
    instance = MyClass()
    instance.do_thing()

test_main.py:

from main import my_func
import unittest
from unittest.mock import patch


class TestMain(unittest.TestCase):
    @patch('main.MyClass')
    def test_my_func(self, MockMyClass):
        mock_my_class_instance = MockMyClass.return_value
        my_func()
        mock_my_class_instance.do_thing.assert_called_once()


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

带有覆盖率报告的单元测试结果:

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

OK
Name                                      Stmts   Miss  Cover   Missing
-----------------------------------------------------------------------
src/stackoverflow/60539392/main.py            4      0   100%
src/stackoverflow/60539392/my_class.py        5      2    60%   3, 6
src/stackoverflow/60539392/test_main.py      10      0   100%
-----------------------------------------------------------------------
TOTAL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-29
    • 2012-08-30
    • 2014-05-06
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 2015-08-23
    相关资源
    最近更新 更多