Я пытаюсь смоделировать асинхронный метод, который используется внутри другого асинхронного метода, который я пытаюсь протестировать.
Я могу исправить первый фиктивный метод, который должен возвращать только примитивное значение 11000
. И это так.
Но сложный объект 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) # WORKS
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
Я также пытался издеваться над объектом вместо метода:
mocker.patch.object(OrderMgr, "get_order", patched_order)
Это возвращает ту же ошибку.
какие-нибудь подсказки о том, как издеваться над сложными объектами?
Код выше был правильным. Мне просто нужно было добавить метод __getitem__
в класс, который я хочу имитировать: класс OrderMgr
.
def __getitem__(self, key):
return self.__dict__[key]
Что это делает? Это делает (в данном случае фиктивный движок) доступной скобочную нотацию - в дополнение к точечной нотации.
точечная запись:
orderMgr.get_order
скобка-обозначение:
orderMgr['get_order']
Да, это также относится к методам/функциям. И вы получите ту же ошибку, если попытаетесь получить доступ к фиктивному атрибуту — ЕСЛИ — метод __getitem__
недоступен.
(Я сделал предположение, что SQLModel/Pydantic сгенерирует getitem. Это не так).