使用mock.patch后函数仍调用真实API,如何解决?
问题解决:Mock失效导致调用真实API
核心原因:Mock路径错误
你当前Mock的是函数A的定义模块(比如get_average.retrieve_all_ip_addresses),但Python的Mock机制要求你Mock的是函数B所在模块中实际导入并使用的函数A引用——也就是函数B"看到"的那个函数A,而不是函数A原本的定义位置。
举个例子:
假设你的display_unhealthy_services函数在模块service_checker.py中,并且是这样导入函数A的:
# service_checker.py from get_average import retrieve_all_ip_addresses from get_ip_info import get_ip_status_info
那你需要Mock的路径是service_checker.retrieve_all_ip_addresses和service_checker.get_ip_status_info,而不是原模块的路径。
修正后的测试代码
假设display_unhealthy_services所在模块名为service_checker.py,修正后的测试代码如下:
@mock.patch("service_checker.retrieve_all_ip_addresses", return_value=["8.8.8.8", "8.8.8.9"]) @mock.patch("service_checker.get_ip_status_info") def test_display_unhealthy_services_if_they_exist(mock_ip_status, mock_ip_addresses): # 设置get_ip_status_info的返回值 mock_ip_status.side_effect = [ ("8.8.8.8", "service1", "Healthy", 40, 50), ("8.8.8.9", "service2", "Unhealthy", 90, 30) ] runner = CliRunner() result = runner.invoke(display_unhealthy_services) # 注意:原预期输出有误——service2是Unhealthy状态,不会被计入健康实例统计 # 实际应该是service1(仅1个健康实例)被判定为不健康服务 expected_output = "Services with less than 2 healthy instances include: \nservice1" assert expected_output in result.output # 验证函数调用次数和参数 mock_ip_status.assert_has_calls([ mock.call("8.8.8.8"), mock.call("8.8.8.9") ]) mock_ip_addresses.assert_called_once()
额外注意事项
- 若你的导入方式是
import get_average,然后用get_average.retrieve_all_ip_addresses()调用,那Mock路径要改成service_checker.get_average.retrieve_all_ip_addresses - Mock装饰器的顺序是从下往上生效的,所以测试函数的参数顺序要和装饰器顺序相反(最后一个装饰器对应的Mock对象放在参数最前面)
- 仔细核对函数逻辑:原函数只会统计Healthy状态的实例,Unhealthy的服务不会被加入
healthy_entries,自然不会出现在最终的不健康服务列表里
内容的提问来源于stack exchange,提问作者cheuk209
相关产品推荐
相关产品推荐

