为何create_autospec传入额外关键字参数无法配置生成的Mock?
create_autospec 嵌套属性配置失效问题说明 问题场景
存在如下待打桩的类定义:
class Class: def method(self): return 1
原有可用的Mock实现
此前使用基础Mock构造器打桩的逻辑可正常实现“调用实例method方法固定返回0”的需求:
from unittest.mock import Mock ClassMock = Mock(Class, **{'return_value.method.return_value': 0}) instance = ClassMock()
运行验证结果符合预期:
>>> instance.method() 0
切换为create_autospec后的异常表现
替换为自动打桩函数create_autospec实现相同配置逻辑时,方法返回值配置未生效:
from unittest.mock import create_autospec ClassMock = create_autospec(Class, **{'return_value.method.return_value': 0}) instance = ClassMock()
运行验证结果为未配置的默认mock返回对象:
>>> instance.method() <MagicMock name='mock().method()' id='139993721092192'>
按照官方文档说明:
create_autospec()也接受任意关键字参数,这些参数会传递给所创建mock的构造器。
上述异常属于预期外的行为偏差。
额外验证:尝试通过instance=True参数直接创建类的实例级mock,通过嵌套参数配置method返回值同样失效:
>>> instance = create_autospec(Class, instance=True, **{'method.return_value': 0}) >>> instance.method() <MagicMock name='mock.method()' id='140603529804824'>
问题根因
上述行为的核心原因是create_autospec的内部执行顺序:
- 所有传入的关键字参数只会在mock对象的初始构造阶段生效,用于给底层Mock实例设置初始属性
- 完成初始构造后,
create_autospec会递归遍历被打桩对象的所有属性(包括类mock的return_value属性、开启instance=True时的整个mock实例对象),为每个属性生成匹配原对象签名的自动打桩对象 - 递归生成自动桩的过程会直接覆盖初始构造阶段设置的同名属性,无论是配置类mock的
return_value.method.return_value,还是配置实例mock的method.return_value,都会被后续生成的自动桩对象替换,最终导致初始传入的配置失效
文档中提到的“关键字参数传递给mock构造器”的描述仅覆盖初始构造阶段的逻辑,未提及后续递归打桩的覆盖行为,属于文档描述未完全覆盖的实现细节,并非功能逻辑错误。
正确使用方式
需要等create_autospec完成全部递归打桩流程后,再手动配置对应方法的返回值,不能在创建阶段通过嵌套关键字参数传值:
- 类mock场景下的正确写法:
from unittest.mock import create_autospec # 先完成全量自动打桩 ClassMock = create_autospec(Class) # 打桩流程结束后,再配置目标方法的返回值 ClassMock.return_value.method.return_value = 0 instance = ClassMock() instance.method() # 固定返回0,符合预期 - 实例级mock场景下的正确写法:
from unittest.mock import create_autospec # 先完成实例的自动打桩 instance = create_autospec(Class, instance=True) # 打桩流程结束后,再配置目标方法的返回值 instance.method.return_value = 0 instance.method() # 固定返回0,符合预期
内容的提问来源于stack exchange,提问作者mportes
相关产品推荐
相关产品推荐

