Python单元测试如何patch模块内未定义也未导入的函数或变量
核心原因
Python导入模块时会逐行执行模块顶层的所有可执行代码,你在测试里的patch操作是在导入demo模块之后才执行的,此时demo里的顶层saySomething()调用已经触发了NameError,所以测试还没运行就已经报错。
可用解决方案
方案1:给顶层执行代码加入口守卫(最推荐)
这是Python通用的模块编写规范,仅在直接运行脚本时才执行顶层业务逻辑,导入时不会触发,修改demo.py代码如下:def saySomething(): return sayHello() if __name__ == "__main__": saySomething() # 后续执行的其他代码 # ...不需要修改测试代码即可正常运行。
方案2:先mock再导入模块(适合无法修改原业务代码的场景)
调整测试代码的执行顺序,在导入demo模块之前就完成sayHello的mock,修改test_demo.py代码如下:from unittest.mock import patch # 先mock,再导入模块 with patch("demo.sayHello", return_value="hello", create=True): import demo def test_fs(): assert demo.saySomething() == "hello"方案3:Databricks场景专属优化
如果是Databricks notebook导出的代码,还可以将所有业务逻辑封装为函数,仅在notebook交互执行时调用入口函数,本地测试时只导入封装好的函数即可,不需要执行顶层调用逻辑。
内容的提问来源于stack exchange,提问作者Hamid
相关产品推荐
相关产品推荐

