问题描述
我正在研究用于机器人的软件,该软件通常在Raspberry Pi上运行.让我们考虑两个文件的导入:
I am working on software for a robot, which is normally run on the Raspberry Pi. Let's consider the imports of two files:
motor.py
(运行电动机):
from RPi import GPIO as gpio
和client.py
(与服务器通信并将命令中继到电动机):
and client.py
(communicates with the server and relays commands to the motors):
from rpi.motor import Motor
两个文件都位于名为rpi
的目录中,该目录包含__init__.py
和__main__.py
. RPi
软件包不能安装在非Rpi设备上.但是,我仍然想测试client.py
的功能.
Both files are in a directory called rpi
, which contains a __init__.py
and a __main__.py
. The RPi
package cannot be installed on non-RPi devices. 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
最初,我在LocA上尝试了from rpi.client import Client
,但是失败了,因为它尝试导入Motor,然后从RPi(不存在)导入GPIO.我也在LocB上尝试了mock.patch("rpi.client.Motor")
(包括在self
之后添加mock_motor
,并在LocC上导入了Client
,但是也失败了.我也尝试在LocA上模拟RPi
,但是它没有用)要么.
Originally, I tried from rpi.client import Client
at LocA, but that failed because it tried to import Motor, and then import GPIO from RPi, which doesn't exist. I also tried mock.patch("rpi.client.Motor")
at LocB (including adding mock_motor
after self
, and imported Client
at LocC, but that failed as well. I tried mocking RPi
at LocA, too, but it didn't work either.
您如何模拟系统中未安装的库?
How do you mock out a library that is not installed on your system?
推荐答案
您可以使用 patch.dict()
修补sys.modules
并模拟RPi
模块,如指向的文档所示.
You can use patch.dict()
to patch sys.modules
and mock RPi
module as showed in pointed documentation.
使用测试模块顶部的遵循代码:
Use follow code at the top of your 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'>
在Python3中,您具有相同的行为.
In Python3 you have same behavior.
在您的特定情况下,使用patch.dict
有点过大;也许您对补丁程序上下文和原始状态恢复不感兴趣.因此,您可以通过直接设置sys.modules["RPi"]
来简化它:
In your specific case use patch.dict
is little bit overkill; maybe you aren't interested in patch context and original state recover. So you can simplify it by 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'>
这篇关于python模拟和未安装的库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!