Pytest MonkeyPatch打桩嵌套PyMongoClient报错:'property'无'command'属性
解决Pytest MonkeyPatch打桩PyMongoClient多层嵌套调用的AttributeError问题
问题原因
你在打桩时犯了一个关键错误:mp.setattr里的lambda返回的是MockPyMongoClient类本身,而不是它的实例。当主代码执行PyMongoClient().db时,实际是在访问类的db属性(也就是一个property对象),而非DbMock实例,所以调用command方法会抛出AttributeError: 'property' object has no attribute 'command'。
修正后的代码
首先调整Mock类的定义(去掉db属性的多余参数),然后修正打桩逻辑:
class DbMock: def command(self, *args, **kwargs): return True class MockPyMongoClient: def __init__(self, *args, **kwargs) -> None: pass @property def db(self): # 移除多余的*args, **kwargs,property getter仅接受self参数 return DbMock() # 打桩时返回MockPyMongoClient的实例,而非类本身 mp.setattr('pymongo.MongoClient', lambda *args, **kwargs: MockPyMongoClient(*args, **kwargs))
关键修正点
- 返回实例而非类:原代码中lambda返回
MockPyMongoClient类对象,必须改成MockPyMongoClient(*args, **kwargs)来创建并返回实例,这样主代码中PyMongoClient()才能得到客户端实例,进而访问db属性获取DbMock对象。 - 修正property参数:
@property装饰的getter方法只能接受self作为参数,原代码中db属性定义的*args, **kwargs无效,会导致潜在问题,需要移除。
验证效果
修正后,主代码执行py_mongo_db = PyMongoClient(settings.MONGODB_HOST).db时,py_mongo_db会是DbMock的实例,调用command('ping')会返回True,不会触发异常,最终会打印MongoDB Healthy。
内容的提问来源于stack exchange,提问作者innicoder
相关产品推荐
相关产品推荐

