[英]Mocking Method Calls In Python
我一直在搜索堆栈交换和网络上如何做到这一点,但我无法理解如何模拟方法的行为。 我正在尝试为自定义类模拟openpyxl行为和行为。 这是我的尝试:
import unittest
from unittest.mock import MagicMock
import openpyxl
from MyPythonFile import MyClass
class TestMyClass(unittest.TestCase):
def test_myclass(self):
myclass = MyClass()
wb = openpyxl.workbook()
ws = openpyxl.worksheet()
wbPath = 'wbPath'
openpyxl.load_workbook(wbPath, data_only = True) = MagicMock(return_value=wb)
当我尝试最后一行时,我收到错误“无法分配给函数调用”。 我需要使用patch.object('openpyxl','load_workbook')
吗? 我习惯用Groovy在Java中进行模拟,而且非常简单。
*编辑:想要根据@alxwrd的响应添加测试的最终版本
import unittest
from unittest.mock import MagicMock
import openpyxl
import configparser
from MyPythonFile import MyClass
class TestMyClass(unittest.TestCase):
def test_myclass(self):
myclass = MyClass()
wb = openpyxl.workbook()
ws = openpyxl.worksheet()
config = configparser.ConfigParser()
openpyxl.load_workbook = MagicMock(return_value=wb)
wb.get_sheet_by_name = MagicMock(return_value=ws)
config.sections() = MagicMock(return_value=['Section1'])
config.get = MagicMock(side_effect=['Value1','Value2'])
请注意,config.get使用side_effect参数提供多个返回,因此如果在代码中调用一次config.get()
,则返回'Value1'
,当第二次调用config.get()
时,它返回'Value2'
。
您不能覆盖函数调用 ,但可以覆盖函数本身。
来自文档 :
>>> from unittest.mock import MagicMock >>> thing = ProductionClass() >>> thing.method = MagicMock(return_value=3) >>> thing.method(3, 4, 5, key='value') 3 >>> thing.method.assert_called_with(3, 4, 5, key='value')
所以在你的情况下:
openpyxl.load_workbook = MagicMock(return_value=wb)
您不必在单元测试中导入要模拟的目标。 使用补丁来模拟目标。 假设您的代码具有以下import语句: import openpyxl
。 补丁然后可以在您的测试中用作装饰器 :
import unittest
from unittest import mock
from MyPythonFile import MyClass
class TestMyClass(unittest.TestCase):
@mock.patch('MyPythonFile.openpyxl')
def test_myclass(self, openpyxl_mock):
wb_dummy = 'foo'
openpyxl_mock.load_workbook.return_value = wb_dummy
myclass = MyClass()
myclass.load_workbook() # assuming this calls openpyxl.load_workbook()
请注意,您必须向test方法添加一个参数,该参数将获取模拟对象。
或者作为上下文管理器 :
import unittest
from unittest import mock
from MyPythonFile import MyClass
class TestMyClass(unittest.TestCase):
def test_myclass(self):
with mock.patch('MyPythonFile.openpyxl') as openpyxl_mock:
wb_dummy = 'foo'
openpyxl_mock.load_workbook.return_value = wb_dummy
myclass = MyClass()
myclass.load_workbook() # assuming this calls openpyxl.load_workbook()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.