pytest测试中如何修改方法行为绕过run_commands返回生成的命令
结论
该需求完全可以实现,使用Mock机制或者pytest自带的monkeypatch都可以完成,不需要触发真实的SSH命令执行逻辑,就能验证方法生成的命令是否符合预期,改造后myFunction的运行效果和你给出的等价逻辑完全一致。
方案1:直接通过依赖注入传入Mock对象(推荐)
你的代码里run_commands是通过构造函数注入的依赖,本身就做了很好的解耦,测试时不需要做任何动态补丁,直接传入Mock对象即可:
from unittest.mock import Mock from cisco_driver import myClass def test_command_generation(): # 定义Mock方法,被调用时直接返回传入的命令本身 mock_run_cmd = Mock(side_effect=lambda input_cmd: input_cmd) driver = myClass(run_commands=mock_run_cmd) # 调用目标方法 test_interface = "Gig1/1/1" ret = driver.myFunction(test_interface) # 校验返回值(也就是生成的命令)符合预期 assert ret == f"show interface status {test_interface}" # 可选校验:确认run_commands确实收到了正确的命令参数 mock_run_cmd.assert_called_once_with(f"show interface status {test_interface}")
执行这个测试用例时完全不会触发真实的SSH连接逻辑,所有调用都在Mock对象内部完成。
方案2:使用pytest monkeypatch动态替换方法
如果场景需要,也可以用monkeypatch fixture在测试运行时动态替换实例上的run_commands方法:
from cisco_driver import myClass def test_command_generation_with_monkeypatch(monkeypatch): driver = myClass(run_commands=lambda _: None) # 定义假的执行方法,直接返回传入的命令 def fake_execute(cmd): return cmd # 替换实例上的run_commands属性 monkeypatch.setattr(driver, "run_commands", fake_execute) ret = driver.myFunction("Gig1/1/1") assert ret == "show interface status Gig1/1/1"
这种写法和Mock方案效果一致,运行时会跳过真实的命令执行逻辑,直接返回拼接生成的命令字符串。
注:由于你的代码已经做了依赖注入,优先选择第一种方案即可,写法更简洁也更符合可测试代码的设计逻辑。
内容的提问来源于stack exchange,提问作者Daniel Arapi
相关产品推荐
相关产品推荐

