Files
ashare-data/tests/test_daily_sources_http.py
T
2026-05-17 15:51:10 +08:00

142 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""验证 daily.py 中腾讯/东方财富 HTTP 解析逻辑(不打网络,用 requests.get mock"""
from unittest.mock import patch, MagicMock
from src.fetchers import daily
def _make_response(payload: dict) -> MagicMock:
resp = MagicMock()
resp.json.return_value = payload
return resp
# ── 腾讯解析 ──
def test_tencent_qfqday_parsed_correctly():
"""腾讯 qfqday 数组每项格式: [date, open, close, high, low, volume]"""
payload = {
"data": {
"sh600000": {
"qfqday": [
["2026-05-08", "10.00", "10.50", "10.80", "9.90", "12345"],
["2026-05-09", "10.50", "11.00", "11.20", "10.40", "23456"],
]
}
}
}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_tencent("600000", "20260508", "20260509")
assert rows is not None
assert len(rows) == 2
assert rows[0]["code"] == "600000"
assert rows[0]["date"] == "2026-05-08"
assert rows[0]["open"] == 10.0
assert rows[0]["close"] == 10.5 # 注意: K 线第三位是 close
assert rows[0]["high"] == 10.8
assert rows[0]["low"] == 9.9
assert rows[0]["volume"] == 12345
# 腾讯不返回这些
assert rows[0]["pct_change"] is None
assert rows[0]["amplitude"] is None
def test_tencent_falls_back_to_day_when_no_qfq():
"""qfqday 缺失时退到 day"""
payload = {
"data": {
"sz000001": {
"day": [
["2026-05-08", "10", "10.5", "10.8", "9.9", "100"],
]
}
}
}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_tencent("000001", "20260508", "20260508")
assert rows and rows[0]["close"] == 10.5
def test_tencent_empty_returns_none():
payload = {"data": {"sh600000": {}}}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_tencent("600000", "20260508", "20260508")
assert rows is None
def test_tencent_beijing_returns_none_without_request():
"""北交所代码应直接返回 None,不发起请求"""
with patch.object(daily.requests, "get") as mock_get:
rows = daily._fetch_tencent("920001", "20260508", "20260508")
assert rows is None
mock_get.assert_not_called()
# ── 东方财富解析 ──
def test_eastmoney_kline_parsed_correctly():
"""东方财富 klines 每行: date,open,close,high,low,volume,amount,amplitude,pct_change,change,turnover_rate"""
payload = {
"data": {
"klines": [
"2026-05-08,10.00,10.50,10.80,9.90,12345,123456789,9.0,5.0,0.5,1.2",
]
}
}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_eastmoney("600000", "20260508", "20260508")
assert rows is not None and len(rows) == 1
r = rows[0]
assert r["code"] == "600000"
assert r["date"] == "2026-05-08"
assert r["open"] == 10.0
assert r["close"] == 10.5
assert r["high"] == 10.8
assert r["low"] == 9.9
assert r["volume"] == 12345
assert r["turnover"] == 123456789
assert r["amplitude"] == 9.0
assert r["pct_change"] == 5.0
assert r["change"] == 0.5
assert r["turnover_rate"] == 1.2
def test_eastmoney_handles_empty_optional_fields():
"""空字符串字段应转为 None,不应抛 ValueError"""
payload = {
"data": {
"klines": [
"2026-05-08,10.00,10.50,10.80,9.90,12345,123456789,,,,",
]
}
}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_eastmoney("600000", "20260508", "20260508")
r = rows[0]
assert r["amplitude"] is None
assert r["pct_change"] is None
assert r["change"] is None
assert r["turnover_rate"] is None
def test_eastmoney_no_klines_returns_none():
payload = {"data": {"klines": []}}
with patch.object(daily.requests, "get", return_value=_make_response(payload)):
rows = daily._fetch_eastmoney("600000", "20260508", "20260508")
assert rows is None
def test_eastmoney_request_exception_raises_runtime():
"""网络/JSON 异常应包成 RuntimeError,让上层多源切换逻辑能捕获并切下一源"""
import pytest
def _boom(*_a, **_kw):
raise ConnectionError("network down")
with patch.object(daily.requests, "get", side_effect=_boom):
with pytest.raises(RuntimeError, match="东方财富请求失败"):
daily._fetch_eastmoney("600000", "20260508", "20260508")