Python 3中如何通过Mock测试断言类私有属性的取值?
单元测试断言深层私有属性的最佳实践
用Mock的side_effect拦截上下文(你思路的具体实现)
你可以借助unittest.mock.patch给目标函数打补丁,通过side_effect获取调用时的self参数,完成断言后再调用原函数。示例代码:from unittest.mock import patch def test_private_attr_set(): # 假设目标类是DeepClass,要拦截的是值设置后必调用的after_set_value方法 with patch.object(DeepClass, 'after_set_value') as mock_method: def custom_side_effect(self, *args, **kwargs): # 直接通过self访问私有属性做断言 assert self._private_attr == expected_value # 调用原函数,__wrapped__是原方法的引用 return mock_method.__wrapped__(self, *args, **kwargs) mock_method.side_effect = custom_side_effect # 执行触发属性设置的HTTP请求逻辑 run_http_request_flow()优先测试公开行为,别死磕私有属性
私有属性属于内部实现细节,后续重构很可能改动。如果能通过验证类的公开方法输出、外部依赖的调用情况来间接证明属性设置正确,测试会更健壮。比如这个属性影响后续API返回,直接断言返回结果就行,没必要碰内部属性。直接读取私有属性(不推荐但可用)
如果实在要直接验证,也可以通过反射读取实例的私有属性(虽然耦合性高,但应急能用):# 获取目标类实例 target_instance = get_deep_class_instance() # 直接访问私有属性做断言 assert target_instance._private_attr == expected_value要是属性是用@property定义的,还能用上
PropertyMock来捕获设置动作:from unittest.mock import patch, PropertyMock def test_private_property(): with patch.object(DeepClass, '_private_attr', new_callable=PropertyMock) as mock_attr: run_http_request_flow() # 断言属性被设置为预期值 mock_attr.assert_called_with(expected_value)重构代码降低测试难度
要是你经常需要测试私有属性,说明代码封装可能有问题。可以试试这些调整:- 把私有属性的设置逻辑抽成单独的可测试函数;
- 加个测试专用的访问接口(比如
_get_test_attr()),标注清楚仅供测试用; - 改成依赖注入,让属性能从外部传入,而非内部硬设置。
内容的提问来源于stack exchange,提问作者enkiv2
相关产品推荐
相关产品推荐

