Python unittest mock类和类方法

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (29)

我觉得这可能比较简单,但是我要把头发拉出来让它起作用。我想模拟整个类,然后为这个类的方法之一指定返回值。

我已经看过这里,其他几个问题,当然还有文档。我仍然无法让这个工作。请参阅下面的简单示例。

目录内容tmp

tmp
├── __init__.py
├── my_module.py
└── test_my_module.py

内容my_module.py

class MyClass:
    def __init__(self):
        # Do expensive operations that will be mocked in testing.
        self.a = 7

    def my_method(self):
        # For sake of simple example, always return 1.
        return 1


def create_class_call_method():
    """Create MyClass instance and call its my_method method, returning
    the result."""
    instance = MyClass()
    value = instance.my_method()
    return value

内容test_my_module.py

import unittest
from unittest.mock import patch, Mock

from tmp import my_module


class MyClassTestCase(unittest.TestCase):

    def test_create_class_call_method(self):
        # Attempt to patch MyClass as well as specify a return_value for
        # the my_method method (spoiler: this doesn't work)
        with patch('tmp.my_module.MyClass',
                   my_method=Mock(return_value=2)):
            value = my_module.create_class_call_method()

        self.assertEqual(value, 2)


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

运行结果test_my_module.py

2 != <MagicMock name='MyClass().my_method()' id='140234477124048'>

Expected :<MagicMock name='MyClass().my_method()' id='140234477124048'>
Actual   :2

我尝试过的其他一些事情:

  • 而不是..., my_method=Mock(return_value=2))patch语句中,解压缩字典如下:**{'my_method.return_value': 2}
  • 嵌套with patch语句。外部语句很简单with patch('tmp.my_module.MyClass'):,内部语句尝试修补my_method如下:with patch('tmp.my_module.MyClass.my_method, return_value=2)
  • 使用补丁装饰器而不是上下文管理器
  • 将补丁语句更改为with patch('tmp.my_module.MyClass') as p:然后在with语句内部,尝试设置p如下:p.evaluate = Mock(return_value=2)

感谢任何帮助,谢谢。

提问于
用户回答回答于

我不确定执行情况create_class_call_method,但请尝试以下方法:

from unittest import mock

class MyClassTestCase(unittest.TestCase):
    @mock.patch('tmp.my_module.MyClass.my_method')
    @mock.patch('tmp.my_module.MyClass.__init__')
    def test_create_class_call_method(self, my_class_init, my_method_mock):
        my_class_init.return_value = None
        my_method.return_value = 2

        value = my_module.create_class_call_method()

        self.assertEqual(value, 2)

扫码关注云+社区

领取腾讯云代金券