Mock callable
This module implements infrastructure for mocking callbacks and other callables.
- class MockCallable(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
This class implements a mock callable.
It is useful for when you want to assert that a callable is called, but the callback is called asynchronously, so that you might have to wait a short time for the call to occur.
If you use a regular mock for the callback, your tests will end up littered with sleeps:
antenna_apiu_proxy.start_communicating() communication_state_changed_callback.assert_called_once_with( CommunicationStatus.NOT_ESTABLISHED ) time.sleep(0.1) communication_state_changed_callback.assert_called_once_with( CommunicationStatus.ESTABLISHED )
These sleeps waste time, slow down the tests, and they are difficult to tune: maybe you only need to sleep 0.1 seconds on your development machine, but what if the CI pipeline deploys the tests to an environment that needs 0.2 seconds for this?
This class solves that by putting each call to the callback onto a queue. Then, each time we assert that a callback was called, we get a call from the queue, waiting if necessary for the call to arrive, but with a timeout:
antenna_apiu_proxy.start_communicating() communication_state_changed_callback.assert_next_call( CommunicationStatus.NOT_ESTABLISHED ) communication_state_changed_callback.assert_next_call( CommunicationStatus.ESTABLISHED )
- __init__(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
Initialise a new instance.
- Parameters:
called_timeout (
float
) – how long to wait for a call to occur when we are expecting one. It makes sense to wait a long time for the expected call, as it will generally arrive much much sooner anyhow, and failure for the call to arrive in time will cause the assertion to fail. The default is 5 seconds.not_called_timeout (
float
) – how long to wait for a callback when we are not expecting one. Since we need to wait the full timeout period in order to determine that a callback has not arrived, asserting that a call has not been made can severely slow down your tests. By keeping this timeout quite short, we can speed up our tests, at the risk of prematurely passing an assertion. The default is 0.5
- assert_last_call(*args, **kwargs)
Assert the arguments of the last call to this mock callback.
The “last” call is the last call before an attempt to get the next event times out.
This is useful for situations where we know a device may call a callback several time, and we don’t care too much about the exact order of calls, but we do know what the final call should be.
- Parameters:
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_next_call(*args, **kwargs)
Assert the arguments of the next call to this mock callback.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- Parameters:
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_not_called(timeout=None)
Assert that the callback still has not been called after the timeout period.
This is a slow method because it has to wait the full timeout period in order to determine that the call is not coming. An optional timeout parameter is provided for the situation where you are happy for the assertion to pass after a shorter wait time.
- calls_in_queue(expected_arguments_list)
Docstring.
- get_next_call()
Return the arguments of the next call to this mock callback.
This is useful for situations where you do not know exactly what the arguments of the next call will be, so you cannot use the
assert_next_call()
method. Instead you want to assert some specific properties on the arguments:(args, kwargs) = mock_callback.get_next_call() event_data = args[0].attr_value assert event_data.name == "healthState" assert event_data.value == HealthState.UNKNOWN assert event_data.quality == tango.AttrQuality.ATTR_VALID
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- get_whole_queue()
Return the arguments of all calls to this mock callback currently in the queue.
This is useful for situations where you do not know exactly what order the calls will happen but you do know what the arguments will be. Instead you want to assert that your call is somewhere in the queue.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- class MockCallableDeque(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
An extension to the MockCallable class to allow the queue to be interrogated.
This class alters MockCallable to use a deque instead of a queue and adds the assert_in_deque method which checks the deque for calls to this mock with specific arguments.
It is a special case of a
MockCallable
where the callable will be called in a non-deterministic order.This class allows inspection of the deque to find specific calls.
- __init__(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
Initialise a new instance.
- Parameters:
called_timeout (
float
) – how long to wait for a call to occur when we are expecting one. It makes sense to wait a long time for the expected call, as it will generally arrive much much sooner anyhow, and failure for the call to arrive in time will cause the assertion to fail. The default is 5 seconds.not_called_timeout (
float
) – how long to wait for a callback when we are not expecting one. Since we need to wait the full timeout period in order to determine that a callback has not arrived, asserting that a call has not been made can severely slow down your tests. By keeping this timeout quite short, we can speed up our tests, at the risk of prematurely passing an assertion. The default is 0.5
- assert_all_in_deque(expected_arguments_list)
Assert multiple calls with arguments have been made to this mock.
Assert that a list of calls to the mocked callback with the expected arguments are present anywhere in the deque.
- assert_in_deque(expected_argument)
Assert a single call with argument has been made to this mock.
Assert that a single call to the callback with the expected argument is present in the deque.
- Parameters:
expected_argument (
Any
) – An argument this mock is expected to be called with and found in the deque.- Raises:
AssertionError – if the expected argument was not found.
- Return type:
- assert_next_call_with_keys(expected_argument, fqdn=None)
Assert that the call to this mock with a given key also has the given value.
This method searches the deque for the next call to the mock with the specified key while ignoring other keys. If a match to the key is found then the value must also match. If the key is not found or the value does not match the expected value this method will raise an AssertionError.
- Parameters:
- Raises:
AssertionError – If the key is not found or the value does not match the expected value.
- Return type:
- assert_next_calls_with_keys(expected_arguments_list)
Assert that the calls to this mock with given keys also have the given values.
This method searches the deque for the next calls to the mock with the specified key while ignoring other keys. If a match to the key is found then the value must also match. If the key is not found or the value does not match the expected value this method will raise an AssertionError
- assert_not_called_with_keys(*state_change_keys, fqdn=None)
Assert that this mock has not been called with the given key and fqdn.
Assert that no call to this mock has been made where its state_change argument has the given key(s) and its fqdn keyword- argument matches the specified fqdn.
- Parameters:
- Raises:
AssertionError – If a key is not found or a value does not match an expected value.
- Return type:
- assert_ordered_in_deque(expected_arguments_list)
Assert that the mock has been called with the provided arguments in order.
- Parameters:
expected_arguments_list (
list
[Any
]) – A list of ordered arguments this mock is expected to have been called with.- Raises:
AssertionError – if any argument is not found or they are in a different order.
- Return type:
- get_next_call_with_keys(*state_change_keys, fqdn=None)
Get the next state change with specific keys that this mock was called with.
This method searches the deque for the next call to this mock where the keys of its state_change argument match the specified keys, and the value of its fqdn keyword-argument match the specified fqdn. If a match is found, the corresponding call is removed from the deque, and the dictionary values of the state_change argument with matching keys is returned.
- class MockChangeEventCallback(event_name, called_timeout=5.0, not_called_timeout=0.5, filter_for_change=False)
This class implements a mock change event callback.
It is a special case of a
MockCallable
where the callable expects to be called with event_name, event_value and event_quality arguments (which is howska_sat_lmc.device_proxy.SatDeviceProxy
calls its change event callbacks).- __init__(event_name, called_timeout=5.0, not_called_timeout=0.5, filter_for_change=False)
Initialise a new instance.
- Parameters:
event_name (
str
) – the name of the event for which this callable is a callbackcalled_timeout (
float
) – how long to wait for a call to occur when we are expecting one. It makes sense to wait a long time for the expected call, as it will generally arrive much much sooner anyhow, and failure for the call to arrive in time will cause the assertion to fail. The default is 5 seconds.not_called_timeout (
float
) – how long to wait for a callback when we are not expecting one. Since we need to wait the full timeout period in order to determine that a callback has not arrived, asserting that a call has not been made can severely slow down your tests. By keeping this timeout quite short, we can speed up our tests, at the risk of prematurely passing an assertion. The default is 0.5filter_for_change (
bool
) – filtered?
- assert_last_change_event(value, _do_assert=True, quality=tango.AttrQuality.ATTR_VALID)
Assert the arguments of the last call to this mock callback.
The “last” call is the last call before an attempt to get the next event times out.
This is useful for situations where we know a device may fire several events, and we don’t know or care about the exact order of events, but we do know what the final event should be. For example, when we tell MccsController to turn on, it has to turn many devices on, which have to turn many devices on, etc. With so m
- Parameters:
value (
Any
) – the asserted value of the change eventquality (
AttrQuality
) – the asserted quality of the change event. This is optional, with a default of ATTR_VALID._do_assert (
bool
) – option to not perform an assert (useful for debugging).
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_next_change_event(value, quality=tango.AttrQuality.ATTR_VALID)
Assert the arguments of the next call to this mock callback.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- Parameters:
value (
Any
) – the asserted value of the change eventquality (
AttrQuality
) – the asserted quality of the change event. This is optional, with a default of ATTR_VALID.
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_not_called()
Assert if not called.
- Raises:
AssertionError – change event callback
- Return type:
- get_next_change_event()
Return the attribute value in the next call to this mock change event callback.
This is useful for situations where you do not know exactly what the value will be, so you cannot use the
assert_next_change_event()
method. Instead you want to assert some specific properties on the arguments.- Raises:
AssertionError – if the callback has not been called
- Return type:
- Returns:
an (args, kwargs) tuple