如何用pytest+monkeypatch复用Mock可调用类LLMChain的__call__返回值?
解决LangChain LLMChain可复用Mock类问题
问题分析
之前的两种模拟方案存在核心问题:
- 类属性设置返回值未生效:大概率是
__call__方法未正确引用类属性,或monkeypatch替换的路径有误。 - 替换LLMChain为实例导致调用报错:原代码中存在
LLMChain(...)实例化逻辑,若将LLMChain类替换为实例对象,调用LLMChain()会变成尝试调用实例,触发“dict不可调用”错误。
可复用MockLLMChain实现
以下是支持动态控制返回值的Mock类,无需在每个测试用例中重写:
class MockLLMChain: # 类级别全局默认返回值,可跨测试修改 mock_response = {"text": "默认模拟输出"} def __init__(self, *args, **kwargs): # 实例化时可传入自定义返回值,优先级高于类级别 self.instance_response = kwargs.pop("mock_response", None) def __call__(self, *args, **kwargs): # 优先返回实例自定义值,无则使用类全局值 return self.instance_response or MockLLMChain.mock_response
使用方式
1. 全局统一返回值(适用于批量测试)
# 修改类全局返回值 MockLLMChain.mock_response = {"text": "全局测试专用返回"} # 替换目标模块中的LLMChain类 monkeypatch.setattr("your_target_module.LLMChain", MockLLMChain)
2. 单个测试用例自定义返回值
# 方式一:实例化时传入专属返回值 # 若原代码是动态实例化LLMChain,可通过kwargs传入 monkeypatch.setattr("your_target_module.LLMChain", MockLLMChain) # 原代码中的LLMChain(..., mock_response={"text": "单测专属返回"})会自动生效 # 方式二:临时修改类全局值(测试后恢复) original_response = MockLLMChain.mock_response MockLLMChain.mock_response = {"text": "单测专属返回"} monkeypatch.setattr("your_target_module.LLMChain", MockLLMChain) # 执行测试逻辑... # 测试完成后恢复默认值 MockLLMChain.mock_response = original_response
关键注意事项
- 确保monkeypatch替换的是目标代码中实际导入LLMChain的路径,而非LangChain源码路径。
- 若需模拟异步
__call__,可添加async def __call__方法适配异步场景。
内容的提问来源于stack exchange,提问作者Erik Jacobs
相关产品推荐
相关产品推荐

