Files
Hydra-Engine/tests/test_supplemental_orderbook.py
2026-03-30 13:19:11 +09:00

81 lines
2.5 KiB
Python

# tests/test_supplemental_orderbook.py
import asyncio
import json
import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from hydra.supplemental.orderbook import OrderBookPoller
@pytest.fixture
def mock_redis():
r = MagicMock()
r.keys = MagicMock(return_value=[
"hydra:indicator:binance:BTC/USDT:1m",
"hydra:indicator:binance:ETH/USDT:1h",
])
r.set = AsyncMock()
return r
@pytest.fixture
def poller(mock_redis):
return OrderBookPoller(redis_client=mock_redis, interval_sec=1)
def test_get_active_symbols_deduplicates(poller, mock_redis):
mock_redis.keys = MagicMock(return_value=[
"hydra:indicator:binance:BTC/USDT:1m",
"hydra:indicator:binance:BTC/USDT:1h",
"hydra:indicator:binance:ETH/USDT:1m",
])
symbols = poller._get_active_symbols()
assert ("binance", "BTC/USDT") in symbols
assert ("binance", "ETH/USDT") in symbols
assert len(symbols) == 2
def test_fetch_one_returns_orderbook(poller):
mock_ob = {
"bids": [[49998.0, 1.5], [49997.0, 2.0]],
"asks": [[50002.0, 1.2], [50003.0, 1.8]],
}
mock_exchange = MagicMock()
mock_exchange.fetch_order_book.return_value = mock_ob
poller._get_exchange = MagicMock(return_value=mock_exchange)
result = poller._fetch_one("binance", "BTC/USDT")
assert result is not None
assert result["bid"] == 49998.0
assert result["ask"] == 50002.0
assert "spread_pct" in result
assert "ts" in result
def test_fetch_one_returns_none_on_error(poller):
mock_exchange = MagicMock()
mock_exchange.fetch_order_book.side_effect = Exception("connection error")
poller._get_exchange = MagicMock(return_value=mock_exchange)
result = poller._fetch_one("binance", "BTC/USDT")
assert result is None
@pytest.mark.asyncio
async def test_run_writes_redis(poller, mock_redis):
mock_ob = {
"bids": [[49998.0, 1.5]],
"asks": [[50002.0, 1.2]],
}
mock_exchange = MagicMock()
mock_exchange.fetch_order_book.return_value = mock_ob
poller._get_exchange = MagicMock(return_value=mock_exchange)
with patch("hydra.supplemental.orderbook.asyncio.sleep",
side_effect=asyncio.CancelledError):
try:
await poller.run()
except asyncio.CancelledError:
pass
assert mock_redis.set.call_count == 2 # BTC/USDT and ETH/USDT
key = mock_redis.set.call_args_list[0][0][0]
assert key.startswith("hydra:orderbook:binance:")
data = json.loads(mock_redis.set.call_args_list[0][0][1])
assert "bid" in data