Python中unittest.mock MagicMock对象布尔值为False导致类初始化测试异常的技术咨询
要解决这个问题,你只需要在使用patch上下文管理器时,显式设置mock对象的__bool__方法返回True即可,这样client or Client()就会正确使用你传入的mock实例:
with patch("Client", autospec=True) as mock_client: # 让mock对象的布尔值为True mock_client.__bool__.return_value = True my_class = MyClass(client=mock_client) my_class.encode() # 你的断言逻辑...
另外,如果你其实是想传入Client实例的mock(这可能是更符合业务逻辑的测试方式,毕竟你的MyClass预期接收的是Client实例而非类),可以直接创建一个带spec的Mock实例(而非通过patch类),这种情况下Mock的默认布尔值就是True:
from unittest.mock import Mock # 创建一个符合Client接口的实例mock mock_client = Mock(spec=Client) mock_client.encode.return_value = "your_expected_result" my_class = MyClass(client=mock_client) my_class.encode() mock_client.encode.assert_called_once()
这是设计特性,不是Bug。根据unittest.mock的设计,MagicMock作为Mock的子类,默认会为大部分特殊方法提供“安全”的默认返回值:
__bool__默认返回False__len__默认返回0- 数值相关的特殊方法默认返回
0 - 迭代相关的特殊方法默认返回空迭代器
这样设计的目的是避免在测试中因为未显式设置特殊方法的行为而导致意外的真值判断或其他逻辑错误,迫使开发者明确指定需要的特殊方法行为。
而你提到的mock_client = patch("Client", autospec=True)返回的是_patch对象(而非Mock实例),它的布尔值为True是因为_patch类本身的__bool__返回True,但此时它还没有被激活为Mock对象,自然没有encode方法,所以调用会报错——这是正常的,因为patch必须作为上下文管理器或装饰器使用才能生效。
另外,autospec=True虽然会让Mock模仿原类的接口,但它不会自动继承原类的特殊方法行为(比如类对象本身的__bool__返回True),所以仍然需要你手动设置__bool__.return_value来改变布尔值。
内容的提问来源于stack exchange,提问作者Carsten

