如何在Streamlit单元测试中Mock函数?解决Mock失效问题
问题原因
AppTest.from_file会在独立的上下文中执行目标脚本,测试函数中对foo模块的patch不会作用到这个独立上下文中的脚本实例,导致mock未生效。同时原代码在模块级别直接调用dialog_func(),脚本执行时会优先使用自身模块的原函数而非被patch的版本。
解决方案
方案一:调整应用代码结构(推荐)
将模块级的执行逻辑封装为函数,避免脚本自动执行,测试时手动触发调用。
修改后的foo.py:
import streamlit as st def dialog_func(): result = dummy_func() st.write(result) def dummy_func(): return 'foo' # 封装应用入口函数 def main(): dialog_func() if __name__ == "__main__": main()
对应的test_foo.py:
from unittest.mock import patch import foo from streamlit.testing.v1 import AppTest def test_foo(): # patch foo模块中的dummy_func with patch("foo.dummy_func") as mock_dummy: mock_dummy.return_value = 'bar' # 创建AppTest实例并手动调用入口函数 at = AppTest.from_file("foo.py").run(lambda: foo.main()) # 验证st.write的输出内容 assert at.markdown[0].value == 'bar'
方案二:不修改原代码,适配patch目标
利用脚本运行时的模块名(__main__)进行patch,直接作用于AppTest执行上下文的函数。
修改后的test_foo.py:
from unittest.mock import patch from streamlit.testing.v1 import AppTest def test_foo(): # 针对脚本运行时的__main__模块patch dummy_func with patch("__main__.dummy_func") as mock_dummy: mock_dummy.return_value = 'bar' at = AppTest.from_file("foo.py").run() assert at.markdown[0].value == 'bar'
内容的提问来源于stack exchange,提问作者94621
相关产品推荐
相关产品推荐

