Reputation: 10772
I'm attempting to mock RPi.GPIO
in python code to do some unit testing.
The problem I have is that my import of RPi.GPIO
fails when called in my unit tests which do not run on the actual Raspberry Pi.
e.g.
tests.py
import iohandler
...
...
iohandler.py
import RPi.GPIO
def function_to_test():
pass
The problem here is that for tests to run it must import iohandler
which in turn must import RPi.GPIO
. This fails as RPi.GPIO
is not installed on the machine which will run the tests.
I've attempted to try and trick the modules after looking at another answer on this site as follows:
tests.py
import sys
import gpiomock # this is a file on the file system
sys.modules["RPi.GPIO"] = gpiomock.GPIO()
import iohandler # the .py file that contains the actual GPIO import
gpiomock.py
class GPIO():
...
...
As sys.modules
is just a dictionary I would have thought this would work as I am providing a key for lookup of RPi.GPIO
and also what I want to replace it with. However I get the following error message.
ImportError: No module named RPi.GPIO
It feels like the nested structure of the actual RPi.GPIO
library is causing this not to work.
Any suggestions on how I can make this work?
Upvotes: 8
Views: 3905
Reputation: 791
Try Mock.GPIO library
after installation, you could use it as follows
try:
import RPi.GPIO as GPIO
except:
import Mock.GPIO as GPIO
Upvotes: 7
Reputation: 10772
Managed to get this working by using this example from Reddit which I will reproduce below:
https://www.reddit.com/r/Python/comments/5eddp5/mock_testing_rpigpio/#ampf=undefined
tests.py
from mock import MagicMock, patch
MockRPi = MagicMock()
modules = {
"RPi": MockRPi,
"RPi.GPIO": MockRPi.GPIO,
}
patcher = patch.dict("sys.modules", modules)
patcher.start()
# Then for the actual test
with patch("RPi.GPIO.output") as mock_gpio:
# Invoke the code to test GPIO
mock_gpio.assert_called_with(....)
Upvotes: 5