11import asyncio
22import re
33from itertools import repeat
4- from unittest .mock import MagicMock , call
4+ from unittest .mock import ANY , MagicMock , call
55
66import pytest
77
88from ophyd_async .core import MockSignalBackend , SignalRW
99from ophyd_async .core .device import Device , DeviceCollector
1010from ophyd_async .core .mock_signal_utils import (
11- assert_mock_put_called_with ,
1211 callback_on_mock_put ,
12+ get_mock_put ,
1313 mock_puts_blocked ,
1414 reset_mock_put_calls ,
1515 set_mock_put_proceeds ,
1616 set_mock_value ,
1717 set_mock_values ,
1818)
19- from ophyd_async .core .signal import (
20- SignalW ,
21- soft_signal_r_and_setter ,
22- soft_signal_rw ,
23- )
19+ from ophyd_async .core .signal import SignalW , soft_signal_r_and_setter , soft_signal_rw
2420from ophyd_async .core .soft_signal_backend import SoftSignalBackend
2521from ophyd_async .epics .signal .signal import epics_signal_r , epics_signal_rw
2622
@@ -31,6 +27,7 @@ async def test_mock_signal_backend(connect_mock_mode):
3127 # If mock is false it will be handled like a normal signal, otherwise it will
3228 # initalize a new backend from the one in the line above
3329 await mock_signal .connect (mock = connect_mock_mode )
30+ assert isinstance (mock_signal ._backend , MockSignalBackend )
3431
3532 assert await mock_signal ._backend .get_value () == ""
3633 await mock_signal ._backend .put ("test" )
@@ -74,6 +71,8 @@ async def test_set_mock_put_proceeds():
7471 mock_signal = SignalW (SoftSignalBackend (str ))
7572 await mock_signal .connect (mock = True )
7673
74+ assert isinstance (mock_signal ._backend , MockSignalBackend )
75+
7776 assert mock_signal ._backend .put_proceeds .is_set () is True
7877
7978 set_mock_put_proceeds (mock_signal , False )
@@ -95,6 +94,7 @@ async def test_set_mock_put_proceeds_timeout():
9594async def test_put_proceeds_timeout ():
9695 mock_signal = SignalW (SoftSignalBackend (str ))
9796 await mock_signal .connect (mock = True )
97+ assert isinstance (mock_signal ._backend , MockSignalBackend )
9898
9999 assert mock_signal ._backend .put_proceeds .is_set () is True
100100
@@ -112,14 +112,14 @@ async def test_mock_utils_throw_error_if_backend_isnt_mock_signal_backend():
112112 set_mock_value (signal , 10 )
113113 exc_msgs .append (str (exc .value ))
114114 with pytest .raises (AssertionError ) as exc :
115- assert_mock_put_called_with (signal , 10 )
115+ get_mock_put (signal ). assert_called_once_with ( 10 )
116116 exc_msgs .append (str (exc .value ))
117117 with pytest .raises (AssertionError ) as exc :
118- async with mock_puts_blocked (signal , 10 ):
118+ async with mock_puts_blocked (signal ):
119119 ...
120120 exc_msgs .append (str (exc .value ))
121121 with pytest .raises (AssertionError ) as exc :
122- with callback_on_mock_put (signal , 10 ):
122+ with callback_on_mock_put (signal , lambda x : _ ):
123123 ...
124124 exc_msgs .append (str (exc .value ))
125125 with pytest .raises (AssertionError ) as exc :
@@ -137,16 +137,13 @@ async def test_mock_utils_throw_error_if_backend_isnt_mock_signal_backend():
137137 )
138138
139139
140- async def test_assert_mock_put_called_with ():
140+ async def test_get_mock_put ():
141141 mock_signal = epics_signal_rw (str , "READ_PV" , "WRITE_PV" , name = "mock_name" )
142142 await mock_signal .connect (mock = True )
143143 await mock_signal .set ("test_value" , wait = True , timeout = 100 )
144144
145- # can leave out kwargs
146- assert_mock_put_called_with (mock_signal , "test_value" )
147- assert_mock_put_called_with (mock_signal , "test_value" , wait = True )
148- assert_mock_put_called_with (mock_signal , "test_value" , timeout = 100 )
149- assert_mock_put_called_with (mock_signal , "test_value" , wait = True , timeout = 100 )
145+ mock = get_mock_put (mock_signal )
146+ mock .assert_called_once_with ("test_value" , wait = True , timeout = 100 )
150147
151148 def err_text (text , wait , timeout ):
152149 return (
@@ -162,7 +159,7 @@ def err_text(text, wait, timeout):
162159 ("test_value" , False , 0 ), # wait and timeout wrong
163160 ]:
164161 with pytest .raises (AssertionError ) as exc :
165- assert_mock_put_called_with ( mock_signal , text , wait = wait , timeout = timeout )
162+ mock . assert_called_once_with ( text , wait = wait , timeout = timeout )
166163 for err_substr in err_text (text , wait , timeout ):
167164 assert err_substr in str (exc .value )
168165
@@ -216,10 +213,8 @@ async def test_callback_on_mock_put_no_ctx():
216213 mock_signal = SignalRW (SoftSignalBackend (float ))
217214 await mock_signal .connect (mock = True )
218215 calls = []
219- (
220- callback_on_mock_put (
221- mock_signal , lambda * args , ** kwargs : calls .append ({** kwargs , "_args" : args })
222- ),
216+ callback_on_mock_put (
217+ mock_signal , lambda * args , ** kwargs : calls .append ({** kwargs , "_args" : args })
223218 )
224219 await mock_signal .set (10.0 )
225220 assert calls == [
@@ -249,16 +244,16 @@ def some_function_without_kwargs(arg):
249244async def test_set_mock_values (mock_signals ):
250245 signal1 , signal2 = mock_signals
251246
252- await signal2 .get_value () == "first_value"
247+ assert await signal2 .get_value () == "first_value"
253248 for value_set in set_mock_values (signal1 , ["second_value" , "third_value" ]):
254249 assert await signal1 .get_value () == value_set
255250
256251 iterator = set_mock_values (signal2 , ["second_value" , "third_value" ])
257- await signal2 .get_value () == "first_value"
252+ assert await signal2 .get_value () == "first_value"
258253 next (iterator )
259- await signal2 .get_value () == "second_value"
254+ assert await signal2 .get_value () == "second_value"
260255 next (iterator )
261- await signal2 .get_value () == "third_value"
256+ assert await signal2 .get_value () == "third_value"
262257
263258
264259async def test_set_mock_values_exhausted_passes (mock_signals ):
@@ -300,10 +295,10 @@ async def test_set_mock_values_exhausted_fails(mock_signals):
300295async def test_reset_mock_put_calls (mock_signals ):
301296 signal1 , signal2 = mock_signals
302297 await signal1 .set ("test_value" , wait = True , timeout = 1 )
303- assert_mock_put_called_with (signal1 , "test_value" )
298+ get_mock_put (signal1 ). assert_called_with ( "test_value" , wait = ANY , timeout = ANY )
304299 reset_mock_put_calls (signal1 )
305300 with pytest .raises (AssertionError ) as exc :
306- assert_mock_put_called_with (signal1 , "test_value" )
301+ get_mock_put (signal1 ). assert_called_with ( "test_value" , wait = ANY , timeout = ANY )
307302 # Replacing spaces because they change between runners
308303 # (e.g the github actions runner has more)
309304 assert str (exc .value ).replace (" " , "" ).replace ("\n " , "" ) == (
@@ -350,3 +345,13 @@ async def set(self):
350345 assert await signal .get_value () == 0
351346 backend_put (100 )
352347 assert await signal .get_value () == 100
348+
349+
350+ async def test_when_put_mock_called_with_typo_then_fails_but_calling_directly_passes ():
351+ mock_signal = SignalRW (SoftSignalBackend (int ))
352+ await mock_signal .connect (mock = True )
353+ assert isinstance (mock_signal ._backend , MockSignalBackend )
354+ mock = mock_signal ._backend .put_mock
355+ with pytest .raises (AttributeError ):
356+ mock .asssert_called_once () # Note typo here is deliberate!
357+ mock ()
0 commit comments