Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to patch a module that does not exist on the machine running the unit test in python?

I have python code running on a custom SBC, and it uses a custom library to interact with the hardware (call it customlib).

However, I'd like to run some unit tests on the code on my dev machine. I don't want to install this custom library on my machine because it's a laborious and annoying process.

Question: is it possible to patch that library so I can still run unit tests on my dev machine?

app structure:

.
├── app.py
├── sensor
│   ├── __init__.py
│   └── main.py
└── test_sensor.py

app.py doesn't have any code at the moment

# __init__.py
from .main import a
# main.py
import customlib
def a():
  customlib.func()
# test_sensor.py
import unittest
from unittest.mock import patch

class TestBasicSense(unittest.TestCase):
    @patch("sensor.customlib")
    def test_get(self):
        import sensor
        sensor.a()

if __name__ == "main":
    unittest.main()

When I run python -m unittest I'm getting the import error:

  File "/projects/myapp/sensor/main.py", line 2, in <module>
    import customlib
ModuleNotFoundError: No module named 'customlib'

I could create a dummy customlib library and install it on my dev machine, but that seems like unnecessary pollution.

Any help is appreciated.

like image 787
PotatoPeeler Avatar asked Sep 01 '25 10:09

PotatoPeeler


1 Answers

I've used the following in a similar situation: wrap the import in a try/catch block:

# main.py
try:
  import customlib
except:
  customlib = None
# ... the rest of the code

Then patch it in the test, just make sure to patch it in the main.py, not just on the module level:

# test_sensor.py
from unittest.mock import patch
from unittest.mock import MagicMock
import sensor

class TestBasicSense(unittest.TestCase):
    def test_get(self):
        fake_lib = MagicMock()
        fake_lib.func = MagicMock()
        with patch('sensor.main.customlib', new=fake_lib)
            sensor.a()
            fake_lib.func.assert_called()
like image 72
ierdna Avatar answered Sep 03 '25 00:09

ierdna