diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8d7e0b0d8..8c01500fb 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -3901,37 +3901,29 @@ def test_cancel_stoploss_order(default_conf, mocker, exchange_name): @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_cancel_stoploss_order_with_result(default_conf, mocker, exchange_name): default_conf["dry_run"] = False - mock_prefix = "freqtrade.exchange.gate.Gate" - if exchange_name == "okx": - mock_prefix = "freqtrade.exchange.okx.Okx" - mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value={"for": 123}) - mocker.patch(f"{mock_prefix}.fetch_stoploss_order", return_value={"for": 123}) exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name) + mocker.patch.object(exchange, "fetch_stoploss_order", return_value={"for": 123}) res = {"fee": {}, "status": "canceled", "amount": 1234} - mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value=res) - mocker.patch(f"{mock_prefix}.cancel_stoploss_order", return_value=res) + mocker.patch.object(exchange, "cancel_stoploss_order", return_value=res) co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555) assert co == res - mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value="canceled") - mocker.patch(f"{mock_prefix}.cancel_stoploss_order", return_value="canceled") + mocker.patch.object(exchange, "cancel_stoploss_order", return_value="canceled") # Fall back to fetch_stoploss_order co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555) assert co == {"for": 123} exc = InvalidOrderException("") - mocker.patch(f"{EXMS}.fetch_stoploss_order", side_effect=exc) - mocker.patch(f"{mock_prefix}.fetch_stoploss_order", side_effect=exc) + mocker.patch.object(exchange, "fetch_stoploss_order", side_effect=exc) co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555) assert co["amount"] == 555 assert co == {"id": "_", "fee": {}, "status": "canceled", "amount": 555, "info": {}} with pytest.raises(InvalidOrderException): exc = InvalidOrderException("Did not find order") - mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=exc) - mocker.patch(f"{mock_prefix}.cancel_stoploss_order", side_effect=exc) exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name) + mocker.patch.object(exchange, "cancel_stoploss_order", side_effect=exc) exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=123) diff --git a/tests/freqtradebot/test_integration.py b/tests/freqtradebot/test_integration.py index 5d3df4c3b..b5520ae42 100644 --- a/tests/freqtradebot/test_integration.py +++ b/tests/freqtradebot/test_integration.py @@ -60,13 +60,10 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee, cancel_order_mock = MagicMock(side_effect=patch_stoploss) mocker.patch.multiple( EXMS, - create_stoploss=stoploss, fetch_ticker=ticker, get_fee=fee, amount_to_precision=lambda s, x, y: y, price_to_precision=lambda s, x, y: y, - fetch_stoploss_order=stoploss_order_mock, - cancel_stoploss_order_with_result=cancel_order_mock, ) mocker.patch.multiple( @@ -80,6 +77,12 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee, mocker.patch("freqtrade.wallets.Wallets.check_exit_amount", return_value=True) freqtrade = get_patched_freqtradebot(mocker, default_conf) + mocker.patch.multiple( + freqtrade.exchange, + create_stoploss=stoploss, + fetch_stoploss_order=stoploss_order_mock, + cancel_stoploss_order_with_result=cancel_order_mock, + ) freqtrade.strategy.order_types["stoploss_on_exchange"] = True # Switch ordertype to market to close trade immediately freqtrade.strategy.order_types["exit"] = "market" diff --git a/tests/freqtradebot/test_stoploss_on_exchange.py b/tests/freqtradebot/test_stoploss_on_exchange.py index c71621620..1cfedbf7c 100644 --- a/tests/freqtradebot/test_stoploss_on_exchange.py +++ b/tests/freqtradebot/test_stoploss_on_exchange.py @@ -103,7 +103,7 @@ def test_handle_stoploss_on_exchange( trade.is_open = True hanging_stoploss_order = MagicMock(return_value={"id": "13434334", "status": "open"}) - mocker.patch(f"{EXMS}.fetch_stoploss_order", hanging_stoploss_order) + mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", hanging_stoploss_order) assert freqtrade.handle_stoploss_on_exchange(trade) is False hanging_stoploss_order.assert_called_once_with("13434334", trade.pair) @@ -116,7 +116,7 @@ def test_handle_stoploss_on_exchange( trade.is_open = True canceled_stoploss_order = MagicMock(return_value={"id": "13434334", "status": "canceled"}) - mocker.patch(f"{EXMS}.fetch_stoploss_order", canceled_stoploss_order) + mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", canceled_stoploss_order) stoploss.reset_mock() amount_before = trade.amount @@ -149,7 +149,7 @@ def test_handle_stoploss_on_exchange( "amount": enter_order["amount"], } ) - mocker.patch(f"{EXMS}.fetch_stoploss_order", stoploss_order_hit) + mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", stoploss_order_hit) freqtrade.strategy.order_filled = MagicMock(return_value=None) assert freqtrade.handle_stoploss_on_exchange(trade) is True assert log_has_re(r"STOP_LOSS_LIMIT is hit for Trade\(id=1, .*\)\.", caplog) @@ -158,7 +158,7 @@ def test_handle_stoploss_on_exchange( assert freqtrade.strategy.order_filled.call_count == 1 caplog.clear() - mocker.patch(f"{EXMS}.create_stoploss", side_effect=ExchangeError()) + mocker.patch.object(freqtrade.exchange, "create_stoploss", side_effect=ExchangeError()) trade.is_open = True freqtrade.handle_stoploss_on_exchange(trade) assert log_has("Unable to place a stoploss order on exchange.", caplog) @@ -168,8 +168,13 @@ def test_handle_stoploss_on_exchange( # It should try to add stoploss order stop_order_dict.update({"id": "105"}) stoploss.reset_mock() - mocker.patch(f"{EXMS}.fetch_stoploss_order", side_effect=InvalidOrderException()) - mocker.patch(f"{EXMS}.create_stoploss", stoploss) + mocker.patch.multiple( + freqtrade.exchange, + fetch_stoploss_order=MagicMock( + side_effect=InvalidOrderException(), + ), + create_stoploss=stoploss, + ) freqtrade.handle_stoploss_on_exchange(trade) assert len(trade.open_sl_orders) == 1 assert stoploss.call_count == 1 @@ -179,8 +184,7 @@ def test_handle_stoploss_on_exchange( trade.is_open = False trade.open_sl_orders[-1].ft_is_open = False stoploss.reset_mock() - mocker.patch(f"{EXMS}.fetch_order") - mocker.patch(f"{EXMS}.create_stoploss", stoploss) + mocker.patch.multiple(freqtrade.exchange, fetch_order=MagicMock(), create_stoploss=stoploss) assert freqtrade.handle_stoploss_on_exchange(trade) is False assert trade.has_open_sl_orders is False assert stoploss.call_count == 0 @@ -644,8 +648,11 @@ def test_handle_stoploss_on_exchange_trailing( stoploss_order_cancel = deepcopy(stoploss_order_hanging) stoploss_order_cancel["status"] = "canceled" - mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value=stoploss_order_hanging) - mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value=stoploss_order_cancel) + mocker.patch.multiple( + freqtrade.exchange, + fetch_stoploss_order=MagicMock(return_value=stoploss_order_hanging), + cancel_stoploss_order=MagicMock(return_value=stoploss_order_cancel), + ) # stoploss initially at 5% assert freqtrade.handle_trade(trade) is False @@ -671,9 +678,12 @@ def test_handle_stoploss_on_exchange_trailing( return_value={"id": "13434334", "status": "canceled", "fee": {}, "amount": trade.amount} ) stoploss_order_mock = MagicMock(return_value={"id": "so1", "status": "open"}) - mocker.patch(f"{EXMS}.fetch_stoploss_order") - mocker.patch(f"{EXMS}.cancel_stoploss_order", cancel_order_mock) - mocker.patch(f"{EXMS}.create_stoploss", stoploss_order_mock) + mocker.patch.multiple( + freqtrade.exchange, + fetch_stoploss_order=MagicMock(), + cancel_stoploss_order=cancel_order_mock, + create_stoploss=stoploss_order_mock, + ) # stoploss should not be updated as the interval is 60 seconds assert freqtrade.handle_trade(trade) is False @@ -711,8 +721,9 @@ def test_handle_stoploss_on_exchange_trailing( } ), ) - mocker.patch( - f"{EXMS}.cancel_stoploss_order_with_result", + mocker.patch.object( + freqtrade.exchange, + "cancel_stoploss_order_with_result", return_value={"id": "so1", "status": "canceled"}, ) assert len(trade.open_sl_orders) == 1 @@ -786,8 +797,12 @@ def test_handle_stoploss_on_exchange_trailing_error( order_date=dt_now(), ) ) - mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException()) - mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value=stoploss_order_hanging) + mocker.patch.object( + freqtrade.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException() + ) + mocker.patch.object( + freqtrade.exchange, "fetch_stoploss_order", return_value=stoploss_order_hanging + ) time_machine.shift(timedelta(minutes=50)) freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging) assert log_has_re(r"Could not cancel stoploss order abcd for pair ETH/USDT.*", caplog) @@ -799,8 +814,8 @@ def test_handle_stoploss_on_exchange_trailing_error( # Fail creating stoploss order caplog.clear() - cancel_mock = mocker.patch(f"{EXMS}.cancel_stoploss_order") - mocker.patch(f"{EXMS}.create_stoploss", side_effect=ExchangeError()) + cancel_mock = mocker.patch.object(freqtrade.exchange, "cancel_stoploss_order") + mocker.patch.object(freqtrade.exchange, "create_stoploss", side_effect=ExchangeError()) time_machine.shift(timedelta(minutes=50)) freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging) assert cancel_mock.call_count == 2 @@ -932,8 +947,11 @@ def test_handle_stoploss_on_exchange_custom_stop( cancel_order_mock = MagicMock() stoploss_order_mock = MagicMock(return_value={"id": "so1", "status": "open"}) - mocker.patch(f"{EXMS}.cancel_stoploss_order", cancel_order_mock) - mocker.patch(f"{EXMS}.create_stoploss", stoploss_order_mock) + mocker.patch.multiple( + freqtrade.exchange, + cancel_stoploss_order=cancel_order_mock, + create_stoploss=stoploss_order_mock, + ) # stoploss should not be updated as the interval is 60 seconds assert freqtrade.handle_trade(trade) is False @@ -1054,7 +1072,9 @@ def test_execute_trade_exit_sloe_cancel_exception( mocker, default_conf_usdt, ticker_usdt, fee, caplog ) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) - mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException()) + mocker.patch.object( + freqtrade.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException() + ) mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=300)) create_order_mock = MagicMock( side_effect=[ @@ -1114,12 +1134,15 @@ def test_execute_trade_exit_with_stoploss_on_exchange( get_fee=fee, amount_to_precision=lambda s, x, y: y, price_to_precision=lambda s, x, y: y, + ) + freqtrade = FreqtradeBot(default_conf_usdt) + mocker.patch.multiple( + freqtrade.exchange, create_stoploss=stoploss, cancel_stoploss_order=cancel_order, _dry_is_price_crossed=MagicMock(side_effect=[True, False]), ) - freqtrade = FreqtradeBot(default_conf_usdt) freqtrade.strategy.order_types["stoploss_on_exchange"] = True patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 40e2b8266..f288cd0ba 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -386,11 +386,14 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short): mocker.patch.multiple( EXMS, markets=PropertyMock(return_value=markets), - cancel_order=cancel_mock, - cancel_stoploss_order=stoploss_mock, ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) + mocker.patch.multiple( + freqtradebot.exchange, + cancel_order=cancel_mock, + cancel_stoploss_order=stoploss_mock, + ) freqtradebot.strategy.order_types["stoploss_on_exchange"] = True create_mock_trades(fee, is_short) rpc = RPC(freqtradebot) @@ -426,13 +429,17 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short): assert stoploss_mock.call_count == 1 assert res["cancel_order_count"] == 1 - stoploss_mock = mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException) + stoploss_mock = mocker.patch.object( + freqtradebot.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException + ) res = rpc._rpc_delete("3") assert stoploss_mock.call_count == 1 stoploss_mock.reset_mock() - cancel_mock = mocker.patch(f"{EXMS}.cancel_order", side_effect=InvalidOrderException) + cancel_mock = mocker.patch.object( + freqtradebot.exchange, "cancel_order", side_effect=InvalidOrderException + ) res = rpc._rpc_delete("4") assert cancel_mock.call_count == 1 diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index aa5483e88..edfb4ff75 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -1034,8 +1034,7 @@ def test_api_delete_trade(botclient, mocker, fee, markets, is_short): stoploss_mock = MagicMock() cancel_mock = MagicMock() mocker.patch.multiple( - EXMS, - markets=PropertyMock(return_value=markets), + ftbot.exchange, cancel_order=cancel_mock, cancel_stoploss_order=stoploss_mock, )