Python:模拟一个属性或模拟整个类?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (128)

我试图在以下业务代码中模拟Popen实例:

process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
output = process.communicate()[0]
if process.returncode != 0:

这是我的测试代码设置:

@mock.patch('subprocess.Popen.returncode')
@mock.patch('subprocess.Popen.communicate')
def testCommandExecutesCommunicate(self, mock_popen_communicate, mock_popen_returncode):

我也尝试过:

@mock.patch('subprocess.Popen.returncode')
@mock.patch('subprocess.Popen.communicate')
def testCommandExecutesCommunicate(self, mock_popen_communicate, mock_popen_returncode):

在这两种情况下,我都会因为returncode嘲弄而出错

Error
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 329, in run
    testMethod()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mock/mock.py", line 1297, in patched
    arg = patching.__enter__()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mock/mock.py", line 1369, in __enter__
    original, local = self.get_original()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mock/mock.py", line 1343, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <class 'subprocess.Popen'> does not have the attribute 'returncode'

我该如何模仿Popen?我应该以某种方式嘲笑Popen课吗?或者我通过嘲笑方法+属性走在正确的轨道上?

提问于
用户回答回答于

对于单元测试,只是嘲笑全班,模拟subprocess.Popen并设置returncodecommunicate()与设置return_value,如

remove_file.py

def do_cmd(command):
    process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    exit_code = process.communicate()[0]
    return exit_code

test_remove_file.py

class TestDoCmd(unittest.TestCase):

    @mock.patch('remove_file.subprocess.Popen')
    def test_do_cmd(self, mockp):
        # add function
        mockp.returncode.return_value = 'abc'
        mockp.communicate()
        mockp.communicate.return_value = '123'
        file = '/tmp/none.txt'
        remove_file.do_cmd('rm -f {}'.format(file))
        mockp.assert_called_with('rm -f /tmp/none.txt', shell=True, stdout=-1)

扫码关注云+社区

领取腾讯云代金券