I'm implementing a class which uses a can bus instance (Bus instance is static because all object should use the same).
# ./mymodule/__init__.py
import can
class UsingCanBUS:
_bus = can.ThreadSafeBus(channel='can0', bustype='socketcan')
def __init__(self) -> None:
# other code
# v here every object interacts with the bus
self._listener = can.Listener()
self._listener.on_message_received = self._handle_message
def _send_message(self, id, data) -> bool:
msg = can.Message(arbitration_id=id, data=data, extended_id=False)
try:
self._bus.send(msg)
except can.CanError:
return False
else:
return True
This code will eventually run on a raspberry so the can interface is correctly setup in the system.
Now, if I want to unit test any of the class methods or any file in the module the bus tries to initialize and, since I'm not on the target system, it throws an os error (which is to be expected).
The folder structure is as follows:
.
|- mymodule/
| |- __init__.py
| |- utils.py
|
|- tests/
| |- __init__.py
| |- test_utils/
| | |- __init__.py
| | |- test_utils.py
It's not clear to me how I should test this piece of code. I tried patching the can module:
#./tests/test_utils/test_utils.py
import pytest
from unittest.mock import patch
@patch('mymodule.can')
def test_something():
from mymodule.utils import some_function
# This doesn't work as the real python-can methods get called instead of the mocked ones
assert some_function() == expected_result
I don't understand if I'm using the patch decorator wrong or if my approach is completely off course.
I expect every class in the can module imported from mymodule
to be patched with mocked classes but it doesn't seem like it.