0

代码

def test_get_network_info(self):
    with open(dirname(abspath(__file__)) + '/files/fake_network_info.txt', 'r') as mock_network_info:
        with patch('subprocess.check_output', Mock(return_value=mock_network_info.read())):
            self.assertEqual('192.168.1.100', get_network_info()[0])
            self.assertEqual('255.255.255.0', get_network_info()[1])
            self.assertEqual('192.168.1.0', get_network_info()[2])

错误

======================================================================
ERROR: test_get_network_info (tests.test_tools.ToolsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/Documents/overseer/app/tests/test_tools.py", line 21, in test_get_network_info
    with patch('subprocess.check_output', Mock(return_value=mock_network_info.read())):
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1268, in __enter__
    original, local = self.get_original()
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1242, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <module 'subprocess' from '/usr/local/lib/python2.7/dist-packages/twill/other_packages/subprocess.pyc'> does not have the attribute 'check_output'

我的理解

我对这个问题的理解mock是试图模拟twillsubprocess模块而不是 python 模块。

问题

  1. 难道我做错了什么 ?

  2. 如何指定我要修补 pythonsubprocess模块而不是斜纹的模块?(可能已在测试套件中较早导入)**

  3. 还有其他方法可以修补subprocess模块吗?

我试过的

  • 我试过了with patch('tools.subprocess.check_output', ...

不工作。

  • 我厌倦了使用装饰器...

也不起作用

  • 我累了直接给subprocess模块打补丁subprocess.check_output = Mock( ...

可以,但效果不好,因为它不会撤消修补。

更多信息

如果我只运行这个测试而不运行其他测试,它会起作用,因为 twill 的子进程模块从未被导入。但是一旦我使用斜纹运行测试,上面的测试就会失败。

是斜纹布的子进程版本,看起来像是从旧版本的 python 复制粘贴的。它没有任何check_output功能,这就是测试失败的原因。

Twill 的包来自我广泛使用的Flask-Testing插件。我在这里在 github 上提交了一个问题。

我希望可爱的 python 社区的人可以提供帮助。:)

4

1 回答 1

1

看到我在上面的评论,由于斜纹布的不良做法,正确的方法是修复斜纹布,这可能需要一些工作,或者转移到其他东西,但由于你现在严重依赖 Flask-Testing,它不是便宜的举动。

所以这给我们留下了一个肮脏的把戏:确保import subprocess在进口斜纹布之前的任何地方。在内部,这将subprocesssys.modules. 一旦一个模块被加载,所有后续import将不再查看,sys.path而只是使用已经缓存在sys.modules.

不幸的是,这可能不是问题的结束。显然斜纹出于某种原因使用了子进程的补丁版本;并且这些补丁对他不可用,因为将加载普通的内置子进程。它很可能会崩溃或以意想不到的方式运行。如果是这样,那么……回到上面的建议。

于 2013-12-23T02:30:24.287 回答