
本文旨在帮助开发者解决在使用`unittest.mock.patch`时遇到的patch未生效的问题,特别是在涉及`mlflow.pyfunc.load_model`等函数时。我们将深入探讨问题原因,并提供有效的解决方案,确保你的单元测试能够正确地mock依赖项,从而避免因真实环境依赖而导致的测试失败。
在进行单元测试时,我们经常需要使用unittest.mock.patch来模拟外部依赖,以便隔离被测代码,使其在可控的环境下运行。然而,有时我们会遇到patch未生效的情况,导致测试仍然依赖于真实环境,从而引入不确定性和潜在的错误。本文将针对一种常见情况,即使用mlflow.pyfunc.load_model时patch失效的问题,提供解决方案。
问题分析
问题的核心在于mlflow.pyfunc.load_model可能在myClass类的__init__方法中被调用,而装饰器@patch可能在类实例化之前生效,但其效果并未传递到类的内部。换句话说,虽然test_find_most_recent_model函数被装饰器patch了mlflow.pyfunc.load_model,但在myClass的实例instance_test创建时,mlflow.pyfunc.load_model仍然是原始函数,而非mock对象。
立即学习“Python免费学习笔记(深入)”;
解决方案
解决这个问题的方法是在测试函数内部,使用with patch(…)语句来临时替换mlflow.pyfunc.load_model。这种方法确保了在myClass实例创建时,mlflow.pyfunc.load_model已经被mock对象替换。
以下是修改后的测试代码:
from unittest.mock import Mock, patchimport pytestimport mlflowclass myClass: def __init__(self): run_id = self.find_most_recent_model() logged_model = f'mlruns/0/{run_id}/artifacts/pipeline' self.loaded_model = mlflow.pyfunc.load_model(logged_model) def find_most_recent_model(self): # 实际实现,此处仅为示例 return "some_run_id"class Test: @patch('mlflow.MlflowClient.search_runs', Mock(return_value=[Mock(_info=Mock(run_id='mock_run_id'))])) @patch('mlflow.pyfunc.load_model', Mock(return_value=Mock())) def test_find_most_recent_model(self): with patch('mlflow.pyfunc.load_model', return_value=Mock()) as mock_load_model: instance_test = myClass() # 添加断言,验证mock是否被调用 mock_load_model.assert_called()
代码解释
@patch(‘mlflow.MlflowClient.search_runs’, Mock(return_value=[Mock(_info=Mock(run_id=’mock_run_id’))])): 这个patch模拟了mlflow.MlflowClient.search_runs函数的行为,使其返回一个包含mocked run_id的结果。@patch(‘mlflow.pyfunc.load_model’, Mock(return_value=Mock())): 这个patch在函数级别模拟了mlflow.pyfunc.load_model。with patch(‘mlflow.pyfunc.load_model’, return_value=Mock()) as mock_load_model:: 在with语句块内,我们再次patch了mlflow.pyfunc.load_model,并将其mock对象赋值给mock_load_model。这确保了在myClass实例创建时,使用的是mocked load_model。instance_test = myClass(): 创建myClass的实例,此时会调用__init__方法,进而调用被mock的mlflow.pyfunc.load_model。mock_load_model.assert_called(): 添加断言,验证mlflow.pyfunc.load_model是否被调用,确保mock生效。
注意事项
确保patch的目标是正确的。有时,由于导入路径的问题,patch可能无法生效。仔细检查patch的目标字符串是否与实际函数或类的导入路径完全匹配。with patch(…)语句的作用域仅限于with块内部。在块外部,mlflow.pyfunc.load_model将恢复为原始函数。可以使用mock_load_model.assert_called_with(*args, **kwargs)来验证mlflow.pyfunc.load_model是否被调用,以及调用时传递的参数是否符合预期。
总结
当使用unittest.mock.patch时,确保patch的作用域覆盖到目标函数被调用的地方。对于在类初始化方法中调用的函数,使用with patch(…)语句可以确保在实例创建时mock生效。通过添加断言,可以验证mock是否按预期工作。通过以上方法,可以有效地解决Python Mock Patch未生效的问题,提高单元测试的可靠性和可维护性。
以上就是解决Python Mock Patch未生效的问题的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1381568.html
微信扫一扫
支付宝扫一扫