Python mock and libraries that are not installed

I am working on software for a robot that usually runs on a Raspberry Pi. Consider importing two files:

motor.py (starts engines):

 from RPi import GPIO as gpio 

and client.py (communicates with the server and sends commands to the engines):

 from rpi.motor import Motor 

Both files are located in a directory named rpi , which contains __init__.py and __main__.py . The rpi package cannot be installed on devices other than RPi. However, I still want to test the functionality of client.py .

 import unittest from unittest import mock # Location A class TestClient(unittest.TestCase): # Location B setUp(self): # Location C pass 

I initially tried from rpi.client import Client in LocA, but this did not succeed because it tried to import Motor and then import GPIO from RPi, which does not exist. I also tried mock.patch("rpi.client.Motor") in LocB (including adding mock_motor after self and imported Client into LocC, but that also failed). I also tried to taunt rpi in LocA, but that did not work either.

How do you mock a library that is not installed on your system?

+5
source share
1 answer

You can use patch.dict() to fix sys.modules and mock RPi , as shown in the exact documentation.

Use the following code at the top of the test module:

 >>> from mock import MagicMock, patch >>> mymodule = MagicMock() >>> patch.dict("sys.modules", RPi=mymodule).start() >>> from RPi import GPIO as gpio >>> gpio <MagicMock name='mock.GPIO' id='139664555819920'> >>> import os >>> os <module 'os' from '/usr/lib/python2.7/os.pyc'> 

In Python3, you have the same behavior.


In your particular case, using patch.dict bit patch.dict ; you may not be interested in the context of the patch and restoring the original state. Therefore, you can simplify it with set sys.modules["RPi"] directly:

 >>> from unittest.mock import MagicMock >>> mymodule = MagicMock() >>> import sys >>> sys.modules["RPi"] = mymodule >>> from RPi import GPIO as gpio >>> gpio <MagicMock name='mock.GPIO' id='140511459454648'> >>> import os >>> os <module 'os' from '/usr/lib/python3.4/os.py'> 
+6
source

All Articles