如何在Pytest Mock中让side_effect函数接收kwargs参数?
解决Pytest Mock中Side_Effect获取被Mock函数参数的问题
问题分析
你当前的问题出在side_effect函数的参数获取方式:what_to_do_result是通过位置参数接收result值,而非关键字参数,所以kwargs["result"]无法拿到传入的值,需要从args中提取。
修正后的测试代码
import pytest import ninja # 导入被测试的模块 class MyTestException(Exception): pass # 修正side_effect函数:从位置参数args中获取传入的result值 def run_side_effect(*args, **kwargs): # args[0]就是what_to_do_result被调用时传入的第一个参数 raise MyTestException(args[0]) @pytest.fixture(name="resource") def setup_fixture(): # 这里可以添加你的资源初始化逻辑 yield # 资源清理逻辑(如果需要) class TestNinja: @staticmethod def setup_method(): # 每个测试用例执行前的初始化操作 pass @staticmethod def teardown_method(): # 每个测试用例执行后的清理操作 pass @staticmethod def test_my_function_cases(mocker, resource): # Mock what_to_do_result函数,绑定side_effect mock_func = mocker.patch("ninja.what_to_do_result", side_effect=run_side_effect) # 测试用例1:a=1, b=2 → result=3 → 触发what_to_do_result(3) → 抛出携带3的异常 with pytest.raises(MyTestException) as exc_info: ninja.my_function(a=1, b=2) assert exc_info.value.args[0] == 3 # 验证mock函数被调用了1次,参数是3 mock_func.assert_called_once_with(3) # 重置mock的调用记录,避免影响下一个用例 mock_func.reset_mock() # 测试用例2:a=2, b=3 → result=5 → 触发what_to_do_result(5+1=6) → 抛出携带6的异常 with pytest.raises(MyTestException) as exc_info: ninja.my_function(a=2, b=3) assert exc_info.value.args[0] == 6 mock_func.assert_called_once_with(6) # 测试用例3:a=5, b=10 → result=15 → 进入else分支,返回True assert ninja.my_function(a=5, b=10) is True # 验证mock函数没有被调用 mock_func.assert_not_called()
关键修正点
- 参数获取方式:
run_side_effect通过args[0]获取what_to_do_result的位置参数,因为原函数是def what_to_do_result(result):,调用时传的是位置参数。 - 模块导入与函数调用:测试代码中需要导入
ninja模块,调用ninja.my_function而非未定义的ninja_function。 - 用例拆分与验证:每个测试场景单独验证,包括异常携带的值、mock函数的调用次数和参数,确保逻辑符合预期。
内容的提问来源于stack exchange,提问作者PicxyB
相关产品推荐
相关产品推荐

