异步方法测试中Mock复杂Order对象报错:TypeError: 'Order'不可下标访问
问题描述
测试异步方法时,Mock返回原始值(如11000)能正常工作,但Mock返回自定义复杂对象Order时,抛出错误:TypeError: 'Order' object is not subscriptable。
代码示例:
from src.market_mgr import MarketMgr @pytest.mark.asyncio async def test_get_unrealized_profit(mocker): # test setup fixture trade_mgr = TradeMgr() trade0 = Trade(pos_idx=0, market="TSL/USD", price=1000) trade_mgr.save_trade(trade0) # actual test mocker.patch("market_mgr.MarketMgr.get_last_price", return_value=11000) # 正常工作 patched_order = Order(market="TSLA/USD", price=10000) # 抛出TYPEERROR: 'Order' object is not subscriptable mocker.patch("order_mgr.OrderMgr.get_order", return_value=patched_order) profit = await trade_mgr.get_unrealized_profit(0) assert profit == 10 #10% profit
尝试过Mock对象而非方法,仍然报错:
mocker.patch.object(OrderMgr, "get_order", patched_order)
错误原因
这个错误的核心是业务代码中把Order实例当成了可下标访问的类型(如字典、列表),比如出现了order['price']这类写法,但Order是自定义类的实例,只能通过属性访问(如order.price)来获取内部值,不支持下标操作。
另外如果OrderMgr.get_order是异步方法,直接返回Order实例的Mock方式也有问题——异步方法需要返回可等待对象(awaitable),直接返回实例会导致调用时的其他潜在错误。
解决方案
1. 修正业务代码的访问方式
检查trade_mgr.get_unrealized_profit方法中对get_order返回值的处理逻辑,把所有下标访问(如order['price'])改成属性访问(如order.price)。
2. 正确Mock异步方法
如果OrderMgr.get_order是异步方法,需要用AsyncMock来模拟(pytest-mock支持直接使用),确保返回的是可等待对象:
from src.market_mgr import MarketMgr from unittest.mock import AsyncMock @pytest.mark.asyncio async def test_get_unrealized_profit(mocker): # test setup fixture trade_mgr = TradeMgr() trade0 = Trade(pos_idx=0, market="TSL/USD", price=1000) trade_mgr.save_trade(trade0) # actual test mocker.patch("market_mgr.MarketMgr.get_last_price", return_value=11000) patched_order = Order(market="TSLA/USD", price=10000) # 使用AsyncMock模拟异步方法,指定返回值为Order实例 mocker.patch("order_mgr.OrderMgr.get_order", new_callable=AsyncMock, return_value=patched_order) profit = await trade_mgr.get_unrealized_profit(0) assert profit == 10 #10% profit
也可以手动定义一个异步Mock函数:
async def mock_get_order(*args, **kwargs): return patched_order mocker.patch("order_mgr.OrderMgr.get_order", side_effect=mock_get_order)
内容的提问来源于stack exchange,提问作者feder
相关产品推荐
相关产品推荐

