I am unit testing a python code. It has an asyncio loop. The main two functions in this loop have endless while loops. I have tested the non-async parts of the code. I am wondering what is the best strategy to unit test these two functions:
import asyncio
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(run_async_tasks())
.
.
async def run_async_tasks():
# initialize loop and its variables
loop = asyncio.get_event_loop()
queue = asyncio.Queue(maxsize=100)
# Creating Asyncio tasks
task1 = loop.create_task(receive_data(queue), name="receive_data")
task2 = loop.create_task(analyse_data(queue), name="analyse_data")
await asyncio.gather(task1, task2)
async def receive_data(queue):
# Data packets are yielded from an non-ending stream by sync_receive_data_packets
for data_packet in sync_receive_data_packets():
await queue.put(data_packet)
async def analyse_data(queue):
while not termination_signal_received():
data_packet = await queue.get()
sync_data_analysis(data_packet)
queue.task_done()
My question is if/how it is possible to unit test receive_data
and analyse_data
.
The main logic for reading the data (sync_receive_data_packets
) and executing the analysis (sync_data_analysis
) are in non-async functions for the sake of simplicity. They are successfully tested. I am not sure how to test the await queue.put
and await queue.get()
parts especially when they are in endless loops.
In fact I am wondering if these functions can be unit tested as they don't return anything. One puts an item into a queue and the other reads it.
Both functions are not "endless" - the first will end when the generator returned by sync_receive_data_packets
is exhausted, and the other whenever termination_signal_received()
returns True
. Just use mock.patch
to point these two functions to callables under the control of your tests. Your tests should further verify if the queue
is filled for the first function, and if it is consumed and sync_data_analisys
is called with the proper values (it should be patched as well)
Otherwise (if they were being repeated with a while True
, with no stopping conditions), the way to unit test these would be to write a specialized Queue class that would work as a queue, but that could raise an exception under control of the test code when .get
or .put
are called.