使用pytest+mock测试时,无法正确mock被其他类调用的Leave类
问题:Mock被间接调用的Leave类失败
我在尝试Mock被其他类调用的Leave类时测试失败,现有三个模块代码如下:
tree.py
from branch import Branch class Tree: type_of_tree = None branches = None def __init__(self, type_of_tree, branches = 0, default_leaves = 0): self.type_of_tree = type_of_tree self.branches = [] for branch in range(branches): self.create_branch(default_leaves) def create_branch(self, leaves): self.branches.append(Branch(leaves)) def get_leaves(self): return_value = [] for branch in self.branches: return_value.extend(branch.get_leaves()) return return_value
branch.py
import uuid from leave import Leave class Branch: leaves = None identifier = None def __init__(self, leaves=0): self.identifier = str(uuid.uuid4()) self.leaves = [] for leave in range(leaves): self.create_leave() def create_leave(self): self.leaves.append(Leave()) def get_leaves(self): return_value = [] for leave in self.leaves: return_value.append(leave.get_identifier()) return return_value
leave.py
import uuid class Leave: identifier = None def __init__(self): self.identifier = str(uuid.uuid4()) def get_identifier(self): return self.identifier
我的测试代码如下:
from unittest.mock import patch, MagicMock from uuid import uuid4 from tree import Tree FAKE_UUID = str(uuid4()) class TestLeave: def test_leave(self): with patch('leave.Leave') as mock_leave: mock_leave.return_value = MagicMock() mock_leave.get_identifier.return_value = FAKE_UUID tree = Tree("Pine", 1, 1) leaves = tree.get_leaves() assert leaves == [FAKE_UUID]
测试未通过,查阅官方文档后仍未找到解决办法。
解决方法
问题出在两个核心点:
Patch目标路径错误
Branch类在自己的模块(branch.py)中导入了Leave,实际运行时使用的是branch模块内的Leave引用。因此需要patch的是branch.Leave,而非原始的leave.Leave。Mock方法返回值设置错误
get_identifier是Leave实例的方法,必须给mock_leave.return_value(即Mock出来的实例对象)的get_identifier设置返回值,而非直接给mock_leave(Mock类本身)设置。
修正后的测试代码:
from unittest.mock import patch, MagicMock from uuid import uuid4 from tree import Tree FAKE_UUID = str(uuid4()) class TestLeave: def test_leave(self): # 修正patch目标为branch模块中的Leave引用 with patch('branch.Leave') as mock_leave: # 创建Mock实例并设置方法返回值 mock_leave_instance = MagicMock() mock_leave_instance.get_identifier.return_value = FAKE_UUID # 将实例设为Mock类的返回值 mock_leave.return_value = mock_leave_instance tree = Tree("Pine", 1, 1) leaves = tree.get_leaves() assert leaves == [FAKE_UUID]
修改后测试即可正常通过。
内容的提问来源于stack exchange,提问作者Rubén Pozo
相关产品推荐
相关产品推荐

