Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何模拟在单独命名空间中使用的类?_Python_Python 2.7_Namespaces_Mocking_Python Unittest - Fatal编程技术网

Python 如何模拟在单独命名空间中使用的类?

Python 如何模拟在单独命名空间中使用的类?,python,python-2.7,namespaces,mocking,python-unittest,Python,Python 2.7,Namespaces,Mocking,Python Unittest,包结构: pqr/pq.py test.py pqr/pq.py具有以下结构 from pqr.pq import Ab 其中lmn是全局安装的pip模块 pq.py的结构 from lmn import Lm class Ab(): def __init__(self): self.lm = Lm() def echo(self, msg): print msg test.py具有以下结构 from pqr.pq import Ab

包结构:

pqr/pq.py
test.py
pqr/pq.py
具有以下结构

from pqr.pq import Ab
其中lmn是全局安装的pip模块

pq.py的结构

from lmn import Lm

class Ab():

    def __init__(self):
        self.lm = Lm()

    def echo(self, msg):
        print msg
test.py
具有以下结构

from pqr.pq import Ab

如何在这里模拟
Lm()
类,以便测试Ab类中的所有方法?

其实
Lm
来自何处并不重要。您将
Lm
作为全局名称导入到
pqr.pq
命名空间中,因此您只需要在那里替换该名称,而不需要在其他地方替换该名称。这是因为
Ab.\uuu init\uu
方法将在自己的模块中“本地”查找它

因此,使用该命令,您只需修补名称
pqr.pq.Lm

import mock
from pqr.pq import Ab

with mock.patch('pqr.pq.Lm') as mock_lm:
    # within this block, `Lm` in the `pqr.pq` namespace has been replaced
    # by a mock object
    test_instance = Ab()
    # assert that the patch succeeded; .return_value is used because
    # Ab.__init__ *calls* Lm()
    assert test_instance.lm is mock_lm.return_value

另请参阅
mock
文档的第页。

对于测试,您可以使用
mock
模块(在较新的python 3中是标准的,对于较旧的版本,可以从pypi下载)来创建“假”类。有一篇关于模拟库的文章解释了如何做到这一点,我将链接这篇文章,这对我帮助很大。您希望您的test.py文件看起来像下面的代码

from pqr import pq
import mock

class TestLm(unittest.Testcase):

    @mock.patch(pq.LM)
    def test_lm(self, mock_lm):
        my_ab = pq.AB()
        my_ab.echo()
使用
mock
模块,您可以创建一个模块/类的模拟版本,您可以将其用于测试方法,只需在测试方法上方使用装饰器“修补”它即可。这将使用MagicMock对象替换指定模块/类的原始版本,然后将该对象作为第二个参数传递到测试方法中。这个MagicMock实际上并不执行
Lm
的任何功能,但允许您断言它应该如何工作。如果需要,您可以稍后重写功能。然而,有一个陷阱,我链接的指南对此进行了解释。您需要确保从使用Lm的模块导入,而不是以传统方式导入。对于导入,Python创建特定于导入到的模块的模块对象,因此,您需要模拟来自
pq
模块的特定
Lm
对象,以测试其功能。这个库一开始使用起来有点复杂,包含的信息远远超过了一个简单答案所能涵盖的范围,所以我建议大家阅读一下

可以找到
mock
模块的文档。 可以找到Python2.7版本的下载

我本人对
mock
库相当陌生,如果我错了,请随时纠正我


编辑:看到Martijn的答案后,我意识到我忘记了my_ab构造函数中的括号

Python支持猴子补丁。您只需调用
pqr.pq.Lm=your_mockup
Ab
将使用
your_mockup
而不是原始的
Lm
。(这回答了您的问题,但它可能不是最好的测试模式。考虑修改<代码> AB < /代码>的构造函数以允许另一个代码> LM< <代码>实现作为备选方案。)菲利浦谢谢您的回答,但我没有完全理解它,您能给我一个工作代码片段吗?我是测试框架的新手。