Skip to content

Commit 4c3d9b8

Browse files
committed
test: simplify some stoploss test setups
1 parent 23a4260 commit 4c3d9b8

File tree

5 files changed

+69
-45
lines changed

5 files changed

+69
-45
lines changed

tests/exchange/test_exchange.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3901,37 +3901,29 @@ def test_cancel_stoploss_order(default_conf, mocker, exchange_name):
39013901
@pytest.mark.parametrize("exchange_name", EXCHANGES)
39023902
def test_cancel_stoploss_order_with_result(default_conf, mocker, exchange_name):
39033903
default_conf["dry_run"] = False
3904-
mock_prefix = "freqtrade.exchange.gate.Gate"
3905-
if exchange_name == "okx":
3906-
mock_prefix = "freqtrade.exchange.okx.Okx"
3907-
mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value={"for": 123})
3908-
mocker.patch(f"{mock_prefix}.fetch_stoploss_order", return_value={"for": 123})
39093904
exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name)
3905+
mocker.patch.object(exchange, "fetch_stoploss_order", return_value={"for": 123})
39103906

39113907
res = {"fee": {}, "status": "canceled", "amount": 1234}
3912-
mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value=res)
3913-
mocker.patch(f"{mock_prefix}.cancel_stoploss_order", return_value=res)
3908+
mocker.patch.object(exchange, "cancel_stoploss_order", return_value=res)
39143909
co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555)
39153910
assert co == res
39163911

3917-
mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value="canceled")
3918-
mocker.patch(f"{mock_prefix}.cancel_stoploss_order", return_value="canceled")
3912+
mocker.patch.object(exchange, "cancel_stoploss_order", return_value="canceled")
39193913
# Fall back to fetch_stoploss_order
39203914
co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555)
39213915
assert co == {"for": 123}
39223916

39233917
exc = InvalidOrderException("")
3924-
mocker.patch(f"{EXMS}.fetch_stoploss_order", side_effect=exc)
3925-
mocker.patch(f"{mock_prefix}.fetch_stoploss_order", side_effect=exc)
3918+
mocker.patch.object(exchange, "fetch_stoploss_order", side_effect=exc)
39263919
co = exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=555)
39273920
assert co["amount"] == 555
39283921
assert co == {"id": "_", "fee": {}, "status": "canceled", "amount": 555, "info": {}}
39293922

39303923
with pytest.raises(InvalidOrderException):
39313924
exc = InvalidOrderException("Did not find order")
3932-
mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=exc)
3933-
mocker.patch(f"{mock_prefix}.cancel_stoploss_order", side_effect=exc)
39343925
exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name)
3926+
mocker.patch.object(exchange, "cancel_stoploss_order", side_effect=exc)
39353927
exchange.cancel_stoploss_order_with_result(order_id="_", pair="TKN/BTC", amount=123)
39363928

39373929

tests/freqtradebot/test_integration.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,10 @@ def patch_stoploss(order_id, *args, **kwargs):
6060
cancel_order_mock = MagicMock(side_effect=patch_stoploss)
6161
mocker.patch.multiple(
6262
EXMS,
63-
create_stoploss=stoploss,
6463
fetch_ticker=ticker,
6564
get_fee=fee,
6665
amount_to_precision=lambda s, x, y: y,
6766
price_to_precision=lambda s, x, y: y,
68-
fetch_stoploss_order=stoploss_order_mock,
69-
cancel_stoploss_order_with_result=cancel_order_mock,
7067
)
7168

7269
mocker.patch.multiple(
@@ -80,6 +77,12 @@ def patch_stoploss(order_id, *args, **kwargs):
8077
mocker.patch("freqtrade.wallets.Wallets.check_exit_amount", return_value=True)
8178

8279
freqtrade = get_patched_freqtradebot(mocker, default_conf)
80+
mocker.patch.multiple(
81+
freqtrade.exchange,
82+
create_stoploss=stoploss,
83+
fetch_stoploss_order=stoploss_order_mock,
84+
cancel_stoploss_order_with_result=cancel_order_mock,
85+
)
8386
freqtrade.strategy.order_types["stoploss_on_exchange"] = True
8487
# Switch ordertype to market to close trade immediately
8588
freqtrade.strategy.order_types["exit"] = "market"

tests/freqtradebot/test_stoploss_on_exchange.py

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def test_handle_stoploss_on_exchange(
103103
trade.is_open = True
104104

105105
hanging_stoploss_order = MagicMock(return_value={"id": "13434334", "status": "open"})
106-
mocker.patch(f"{EXMS}.fetch_stoploss_order", hanging_stoploss_order)
106+
mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", hanging_stoploss_order)
107107

108108
assert freqtrade.handle_stoploss_on_exchange(trade) is False
109109
hanging_stoploss_order.assert_called_once_with("13434334", trade.pair)
@@ -116,7 +116,7 @@ def test_handle_stoploss_on_exchange(
116116
trade.is_open = True
117117

118118
canceled_stoploss_order = MagicMock(return_value={"id": "13434334", "status": "canceled"})
119-
mocker.patch(f"{EXMS}.fetch_stoploss_order", canceled_stoploss_order)
119+
mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", canceled_stoploss_order)
120120
stoploss.reset_mock()
121121
amount_before = trade.amount
122122

@@ -149,7 +149,7 @@ def test_handle_stoploss_on_exchange(
149149
"amount": enter_order["amount"],
150150
}
151151
)
152-
mocker.patch(f"{EXMS}.fetch_stoploss_order", stoploss_order_hit)
152+
mocker.patch.object(freqtrade.exchange, "fetch_stoploss_order", stoploss_order_hit)
153153
freqtrade.strategy.order_filled = MagicMock(return_value=None)
154154
assert freqtrade.handle_stoploss_on_exchange(trade) is True
155155
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(
158158
assert freqtrade.strategy.order_filled.call_count == 1
159159
caplog.clear()
160160

161-
mocker.patch(f"{EXMS}.create_stoploss", side_effect=ExchangeError())
161+
mocker.patch.object(freqtrade.exchange, "create_stoploss", side_effect=ExchangeError())
162162
trade.is_open = True
163163
freqtrade.handle_stoploss_on_exchange(trade)
164164
assert log_has("Unable to place a stoploss order on exchange.", caplog)
@@ -168,8 +168,13 @@ def test_handle_stoploss_on_exchange(
168168
# It should try to add stoploss order
169169
stop_order_dict.update({"id": "105"})
170170
stoploss.reset_mock()
171-
mocker.patch(f"{EXMS}.fetch_stoploss_order", side_effect=InvalidOrderException())
172-
mocker.patch(f"{EXMS}.create_stoploss", stoploss)
171+
mocker.patch.multiple(
172+
freqtrade.exchange,
173+
fetch_stoploss_order=MagicMock(
174+
side_effect=InvalidOrderException(),
175+
),
176+
create_stoploss=stoploss,
177+
)
173178
freqtrade.handle_stoploss_on_exchange(trade)
174179
assert len(trade.open_sl_orders) == 1
175180
assert stoploss.call_count == 1
@@ -179,8 +184,7 @@ def test_handle_stoploss_on_exchange(
179184
trade.is_open = False
180185
trade.open_sl_orders[-1].ft_is_open = False
181186
stoploss.reset_mock()
182-
mocker.patch(f"{EXMS}.fetch_order")
183-
mocker.patch(f"{EXMS}.create_stoploss", stoploss)
187+
mocker.patch.multiple(freqtrade.exchange, fetch_order=MagicMock(), create_stoploss=stoploss)
184188
assert freqtrade.handle_stoploss_on_exchange(trade) is False
185189
assert trade.has_open_sl_orders is False
186190
assert stoploss.call_count == 0
@@ -644,8 +648,11 @@ def test_handle_stoploss_on_exchange_trailing(
644648
stoploss_order_cancel = deepcopy(stoploss_order_hanging)
645649
stoploss_order_cancel["status"] = "canceled"
646650

647-
mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value=stoploss_order_hanging)
648-
mocker.patch(f"{EXMS}.cancel_stoploss_order", return_value=stoploss_order_cancel)
651+
mocker.patch.multiple(
652+
freqtrade.exchange,
653+
fetch_stoploss_order=MagicMock(return_value=stoploss_order_hanging),
654+
cancel_stoploss_order=MagicMock(return_value=stoploss_order_cancel),
655+
)
649656

650657
# stoploss initially at 5%
651658
assert freqtrade.handle_trade(trade) is False
@@ -671,9 +678,12 @@ def test_handle_stoploss_on_exchange_trailing(
671678
return_value={"id": "13434334", "status": "canceled", "fee": {}, "amount": trade.amount}
672679
)
673680
stoploss_order_mock = MagicMock(return_value={"id": "so1", "status": "open"})
674-
mocker.patch(f"{EXMS}.fetch_stoploss_order")
675-
mocker.patch(f"{EXMS}.cancel_stoploss_order", cancel_order_mock)
676-
mocker.patch(f"{EXMS}.create_stoploss", stoploss_order_mock)
681+
mocker.patch.multiple(
682+
freqtrade.exchange,
683+
fetch_stoploss_order=MagicMock(),
684+
cancel_stoploss_order=cancel_order_mock,
685+
create_stoploss=stoploss_order_mock,
686+
)
677687

678688
# stoploss should not be updated as the interval is 60 seconds
679689
assert freqtrade.handle_trade(trade) is False
@@ -711,8 +721,9 @@ def test_handle_stoploss_on_exchange_trailing(
711721
}
712722
),
713723
)
714-
mocker.patch(
715-
f"{EXMS}.cancel_stoploss_order_with_result",
724+
mocker.patch.object(
725+
freqtrade.exchange,
726+
"cancel_stoploss_order_with_result",
716727
return_value={"id": "so1", "status": "canceled"},
717728
)
718729
assert len(trade.open_sl_orders) == 1
@@ -786,8 +797,12 @@ def test_handle_stoploss_on_exchange_trailing_error(
786797
order_date=dt_now(),
787798
)
788799
)
789-
mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException())
790-
mocker.patch(f"{EXMS}.fetch_stoploss_order", return_value=stoploss_order_hanging)
800+
mocker.patch.object(
801+
freqtrade.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException()
802+
)
803+
mocker.patch.object(
804+
freqtrade.exchange, "fetch_stoploss_order", return_value=stoploss_order_hanging
805+
)
791806
time_machine.shift(timedelta(minutes=50))
792807
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
793808
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(
799814

800815
# Fail creating stoploss order
801816
caplog.clear()
802-
cancel_mock = mocker.patch(f"{EXMS}.cancel_stoploss_order")
803-
mocker.patch(f"{EXMS}.create_stoploss", side_effect=ExchangeError())
817+
cancel_mock = mocker.patch.object(freqtrade.exchange, "cancel_stoploss_order")
818+
mocker.patch.object(freqtrade.exchange, "create_stoploss", side_effect=ExchangeError())
804819
time_machine.shift(timedelta(minutes=50))
805820
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
806821
assert cancel_mock.call_count == 2
@@ -932,8 +947,11 @@ def fetch_stoploss_order_mock(order_id, *args, **kwargs):
932947

933948
cancel_order_mock = MagicMock()
934949
stoploss_order_mock = MagicMock(return_value={"id": "so1", "status": "open"})
935-
mocker.patch(f"{EXMS}.cancel_stoploss_order", cancel_order_mock)
936-
mocker.patch(f"{EXMS}.create_stoploss", stoploss_order_mock)
950+
mocker.patch.multiple(
951+
freqtrade.exchange,
952+
cancel_stoploss_order=cancel_order_mock,
953+
create_stoploss=stoploss_order_mock,
954+
)
937955

938956
# stoploss should not be updated as the interval is 60 seconds
939957
assert freqtrade.handle_trade(trade) is False
@@ -1054,7 +1072,9 @@ def test_execute_trade_exit_sloe_cancel_exception(
10541072
mocker, default_conf_usdt, ticker_usdt, fee, caplog
10551073
) -> None:
10561074
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
1057-
mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException())
1075+
mocker.patch.object(
1076+
freqtrade.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException()
1077+
)
10581078
mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=300))
10591079
create_order_mock = MagicMock(
10601080
side_effect=[
@@ -1114,12 +1134,15 @@ def test_execute_trade_exit_with_stoploss_on_exchange(
11141134
get_fee=fee,
11151135
amount_to_precision=lambda s, x, y: y,
11161136
price_to_precision=lambda s, x, y: y,
1137+
)
1138+
freqtrade = FreqtradeBot(default_conf_usdt)
1139+
mocker.patch.multiple(
1140+
freqtrade.exchange,
11171141
create_stoploss=stoploss,
11181142
cancel_stoploss_order=cancel_order,
11191143
_dry_is_price_crossed=MagicMock(side_effect=[True, False]),
11201144
)
11211145

1122-
freqtrade = FreqtradeBot(default_conf_usdt)
11231146
freqtrade.strategy.order_types["stoploss_on_exchange"] = True
11241147
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
11251148

tests/rpc/test_rpc.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,14 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
386386
mocker.patch.multiple(
387387
EXMS,
388388
markets=PropertyMock(return_value=markets),
389-
cancel_order=cancel_mock,
390-
cancel_stoploss_order=stoploss_mock,
391389
)
392390

393391
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
392+
mocker.patch.multiple(
393+
freqtradebot.exchange,
394+
cancel_order=cancel_mock,
395+
cancel_stoploss_order=stoploss_mock,
396+
)
394397
freqtradebot.strategy.order_types["stoploss_on_exchange"] = True
395398
create_mock_trades(fee, is_short)
396399
rpc = RPC(freqtradebot)
@@ -426,13 +429,17 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
426429
assert stoploss_mock.call_count == 1
427430
assert res["cancel_order_count"] == 1
428431

429-
stoploss_mock = mocker.patch(f"{EXMS}.cancel_stoploss_order", side_effect=InvalidOrderException)
432+
stoploss_mock = mocker.patch.object(
433+
freqtradebot.exchange, "cancel_stoploss_order", side_effect=InvalidOrderException
434+
)
430435

431436
res = rpc._rpc_delete("3")
432437
assert stoploss_mock.call_count == 1
433438
stoploss_mock.reset_mock()
434439

435-
cancel_mock = mocker.patch(f"{EXMS}.cancel_order", side_effect=InvalidOrderException)
440+
cancel_mock = mocker.patch.object(
441+
freqtradebot.exchange, "cancel_order", side_effect=InvalidOrderException
442+
)
436443

437444
res = rpc._rpc_delete("4")
438445
assert cancel_mock.call_count == 1

tests/rpc/test_rpc_apiserver.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,7 @@ def test_api_delete_trade(botclient, mocker, fee, markets, is_short):
10341034
stoploss_mock = MagicMock()
10351035
cancel_mock = MagicMock()
10361036
mocker.patch.multiple(
1037-
EXMS,
1038-
markets=PropertyMock(return_value=markets),
1037+
ftbot.exchange,
10391038
cancel_order=cancel_mock,
10401039
cancel_stoploss_order=stoploss_mock,
10411040
)

0 commit comments

Comments
 (0)