如何用Pytest模拟循环中多次调用的Python方法?测试问题排查
问题分析与修正
你的测试代码存在三个关键问题:
- 语法错误:
self.bad_method() = MagicMock(...)是非法赋值,应该直接给方法对象赋值,去掉括号:self.bad_method = MagicMock(...)。 - side_effect 参数误用:你把
side_effect()的执行结果(单个字典)传给了side_effect,而不是传递函数本身或返回值序列。这会导致bad_method每次调用都返回同一个字典,循环内的resources永远是{"resources": "values"},要么无限循环,要么和你的预期输出不符。 - 缺少类实例化:测试代码里的
self没有定义,需要先创建目标类的实例才能调用方法。
实现预期效果的修正方案
要让good_method先打印{"resources": "values"},再打印"values"然后停止循环,需要让bad_method按顺序返回不同的字典:
- 第一次调用:返回
{"resources": {"resources": "values"}},对应第一次打印的内容 - 第二次调用:返回
{"resources": "values"},对应循环内第一次打印的内容 - 第三次调用:返回
{"resources": None}(或其他假值),让循环条件不成立,终止循环
用MagicMock的side_effect列表可以轻松实现这种多返回值的控制,修正后的测试代码如下:
import unittest from unittest.mock import MagicMock # 导入你的目标类 from your_module import TargetClass class TestTargetClass(unittest.TestCase): def test_good_method(self): # 创建类实例 obj = TargetClass() # 定义bad_method的调用返回序列 obj.bad_method = MagicMock(side_effect=[ {"resources": {"resources": "values"}}, {"resources": "values"}, {"resources": None} ]) # 调用待测试方法 obj.good_method()
如果你的测试不是基于unittest.TestCase,而是普通函数,调整为:
from unittest.mock import MagicMock from your_module import TargetClass def test_good_method(): obj = TargetClass() obj.bad_method = MagicMock(side_effect=[ {"resources": {"resources": "values"}}, {"resources": "values"}, {"resources": None} ]) obj.good_method()
运行这个测试,会依次打印{"resources": "values"}、"values"、None,然后循环终止。如果只需要两次打印,把第二个返回值改成{"resources": ""}(空字符串,假值),这样第二次打印空字符串后直接退出循环。
内容的提问来源于stack exchange,提问作者wikofad877
相关产品推荐
相关产品推荐

