diff --git a/tests/test_http_client.py b/tests/test_http_client.py index ded5d41..2981a4e 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -5,6 +5,22 @@ import requests from unittest.mock import MagicMock + +def mock_requests_get(mocker): + """Patch ``requests.get`` with a mock whose response is fully configured. + + ``BaseRest.request`` checks ``response.status_code >= 400`` to detect HTTP + errors. A bare ``mocker.patch('requests.get')`` returns a MagicMock whose + ``.status_code`` is itself a MagicMock, which cannot be compared with an int + and raises ``TypeError``. We give the mocked response a numeric status code + (200) so tests exercise the intended success path, and return the patched + ``requests.get`` mock so callers can assert on how it was called. + """ + mock_get = mocker.patch('requests.get') + mock_get.return_value.status_code = 200 + return mock_get + + @pytest.fixture def api_key_client(): return RestClient(api_key='api-key') @@ -78,7 +94,7 @@ def test_stock_intraday(self, api_key_client): def test_intraday_tickers_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.tickers(type='INDEX') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/tickers?type=INDEX', @@ -87,7 +103,7 @@ def test_intraday_tickers_api_key(self, mocker, api_key_client): def test_intraday_tickers_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.tickers(type='INDEX') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/tickers?type=INDEX', @@ -96,7 +112,7 @@ def test_intraday_tickers_bearer_token(self, bearer_client, mocker): def test_intraday_ticker_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.ticker(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/ticker/2330', @@ -105,7 +121,7 @@ def test_intraday_ticker_api_key(self, mocker, api_key_client): def test_intraday_ticker_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.ticker(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/ticker/2330', @@ -115,7 +131,7 @@ def test_intraday_ticker_bearer_token(self, bearer_client, mocker): def test_intraday_quote_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.quote(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/quote/2330', @@ -124,7 +140,7 @@ def test_intraday_quote_api_key(self, mocker, api_key_client): def test_intraday_quote_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.quote(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/quote/2330', @@ -133,7 +149,7 @@ def test_intraday_quote_bearer_token(self, bearer_client, mocker): def test_intraday_trades_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.trades(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/trades/2330', @@ -142,7 +158,7 @@ def test_intraday_trades_api_key(self, mocker, api_key_client): def test_intraday_trades_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.trades(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/trades/2330', @@ -151,7 +167,7 @@ def test_intraday_trades_bearer_token(self, bearer_client, mocker): def test_intraday_volumes_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.volumes(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/volumes/2330', @@ -160,7 +176,7 @@ def test_intraday_volumes_api_key(self, mocker, api_key_client): def test_intraday_volumes_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.volumes(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/intraday/volumes/2330', @@ -169,7 +185,7 @@ def test_intraday_volumes_bearer_token(self, bearer_client, mocker): def test_intraday_quote_custom_base_url(self, mocker, custom_base_url_client): stock = custom_base_url_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.intraday.quote(symbol='2330') mock_get.assert_called_once_with( 'https://custom-api.example.com/v2.0/stock/intraday/quote/2330', @@ -184,7 +200,7 @@ def test_stock_historical(self, api_key_client): def test_historical_candles_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.historical.candles(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/historical/candles/2330', @@ -193,7 +209,7 @@ def test_historical_candles_api_key(self, mocker, api_key_client): def test_historical_candles_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.historical.candles(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/historical/candles/2330', @@ -202,7 +218,7 @@ def test_historical_candles_bearer_token(self, bearer_client, mocker): def test_historical_stats_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.historical.stats(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/historical/stats/2330', @@ -211,7 +227,7 @@ def test_historical_stats_api_key(self, mocker, api_key_client): def test_historical_stats_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.historical.stats(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/historical/stats/2330', @@ -227,7 +243,7 @@ def test_stock_historical(self, api_key_client): def test_snapshot_quotes_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.quotes(market='TSE') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/quotes/TSE', @@ -236,7 +252,7 @@ def test_snapshot_quotes_api_key(self, mocker, api_key_client): def test_snapshot_quotes_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.quotes(market='TSE') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/quotes/TSE', @@ -245,7 +261,7 @@ def test_snapshot_quotes_bearer_token(self, bearer_client, mocker): def test_snapshot_movers_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.movers(market='TSE', change='percent', direction='up') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/movers/TSE?change=percent&direction=up', @@ -254,7 +270,7 @@ def test_snapshot_movers_api_key(self, mocker, api_key_client): def test_snapshot_movers_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.movers(market='TSE', change='percent', direction='up') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/movers/TSE?change=percent&direction=up', @@ -263,7 +279,7 @@ def test_snapshot_movers_bearer_token(self, bearer_client, mocker): def test_snapshot_actives_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.actives(market='TSE', trade='volume') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/actives/TSE?trade=volume', @@ -272,7 +288,7 @@ def test_snapshot_actives_api_key(self, mocker, api_key_client): def test_snapshot_actives_bearer_token(self, bearer_client, mocker): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.snapshot.actives(market='TSE', trade='volume') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/snapshot/actives/TSE?trade=volume', @@ -292,7 +308,7 @@ def test_futopt_intraday(self, api_key_client): def test_intraday_products_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.products(type='OPTION') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/products?type=OPTION', @@ -301,7 +317,7 @@ def test_intraday_products_api_key(self, mocker, api_key_client): def test_intraday_tickers_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.tickers(type='OPTION') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/tickers?type=OPTION', @@ -310,7 +326,7 @@ def test_intraday_tickers_api_key(self, mocker, api_key_client): def test_intraday_ticker_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.ticker(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/ticker/2330', @@ -319,7 +335,7 @@ def test_intraday_ticker_api_key(self, mocker, api_key_client): def test_intraday_quote_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.quote(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/quote/2330', @@ -328,7 +344,7 @@ def test_intraday_quote_api_key(self, mocker, api_key_client): def test_intraday_candles_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.candles(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/candles/2330', @@ -337,7 +353,7 @@ def test_intraday_candles_api_key(self, mocker, api_key_client): def test_intraday_trades_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.trades(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/trades/2330', @@ -346,7 +362,7 @@ def test_intraday_trades_api_key(self, mocker, api_key_client): def test_intraday_volumes_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.intraday.volumes(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/intraday/volumes/2330', @@ -361,7 +377,7 @@ def test_futopt_historical(self, api_key_client): def test_historical_candles_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.historical.candles(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/historical/candles/2330', @@ -370,7 +386,7 @@ def test_historical_candles_api_key(self, mocker, api_key_client): def test_historical_candles_bearer_token(self, bearer_client, mocker): futopt = bearer_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.historical.candles(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/historical/candles/2330', @@ -379,7 +395,7 @@ def test_historical_candles_bearer_token(self, bearer_client, mocker): def test_historical_daily_api_key(self, mocker, api_key_client): futopt = api_key_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.historical.daily(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/historical/daily/2330', @@ -388,7 +404,7 @@ def test_historical_daily_api_key(self, mocker, api_key_client): def test_historical_daily_bearer_token(self, bearer_client, mocker): futopt = bearer_client.futopt - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) futopt.historical.daily(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/futopt/historical/daily/2330', @@ -407,7 +423,7 @@ def test_stock_technical(self, api_key_client): def test_technical_sma_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.sma(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/sma/2330', @@ -416,7 +432,7 @@ def test_technical_sma_api_key(self, mocker, api_key_client): def test_technical_sma_bearer_token(self, mocker, bearer_client): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.sma(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/sma/2330', @@ -425,7 +441,7 @@ def test_technical_sma_bearer_token(self, mocker, bearer_client): def test_technical_rsi_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.rsi(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/rsi/2330', @@ -434,7 +450,7 @@ def test_technical_rsi_api_key(self, mocker, api_key_client): def test_technical_rsi_bearer_token(self, mocker, bearer_client): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.rsi(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/rsi/2330', @@ -443,7 +459,7 @@ def test_technical_rsi_bearer_token(self, mocker, bearer_client): def test_technical_kdj_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.kdj(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/kdj/2330', @@ -452,7 +468,7 @@ def test_technical_kdj_api_key(self, mocker, api_key_client): def test_technical_kdj_bearer_token(self, mocker, bearer_client): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.kdj(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/kdj/2330', @@ -461,7 +477,7 @@ def test_technical_kdj_bearer_token(self, mocker, bearer_client): def test_technical_macd_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.macd(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/macd/2330', @@ -470,7 +486,7 @@ def test_technical_macd_api_key(self, mocker, api_key_client): def test_technical_macd_bearer_token(self, mocker, bearer_client): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.macd(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/macd/2330', @@ -479,7 +495,7 @@ def test_technical_macd_bearer_token(self, mocker, bearer_client): def test_technical_bb_api_key(self, mocker, api_key_client): stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.bb(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/bb/2330', @@ -488,7 +504,7 @@ def test_technical_bb_api_key(self, mocker, api_key_client): def test_technical_bb_bearer_token(self, mocker, bearer_client): stock = bearer_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) stock.technical.bb(symbol='2330') mock_get.assert_called_once_with( 'https://api.fugle.tw/marketdata/v1.0/stock/technical/bb/2330', @@ -555,7 +571,7 @@ def test_bearer_token_authentication_preserved(self, bearer_client): def test_existing_api_endpoints_still_work(self, mocker, api_key_client): # 回歸測試:確保現有的 API 端點仍然正常工作 stock = api_key_client.stock - mock_get = mocker.patch('requests.get') + mock_get = mock_requests_get(mocker) # 測試幾個主要的 API 端點 stock.intraday.quote(symbol='2330')