模拟subprocess.Popen而不执行

时间:2017-12-15 10:49:14

标签: python mocking subprocess python-unittest

我正在尝试为调用subprocess.Popen的方法编写单元测试。我要测试的是arg发送给Popen的{​​{1}}参数是否符合预期。我实际上不希望Popen运行。这可能不用嘲笑arg列表吗?

e.g。

def call_something(argument_list):
    binary = '/opt/mybin/'
    Popen([binary] + argument_list)

然后,进行测试。

@mock.patch('subprocess.Popen')
def test_call_something(self, mock_popen):
    binary = '/opt/mybin/'
    args = ['foo', 'bar']

    mock_popen.return_value.returncode = 0
    mock_popen.return_value.communicate.return_value = ('Running', '')

    call_something(args)

    self.assertEqual(
        [binary] + args,
        mock_popen.call_args_list
    )

我遇到的问题是,首先调用二进制文件(我不想要),其次,call_args_list为空。

1 个答案:

答案 0 :(得分:2)

使用mock.patch时,您必须指向导入它的对象

请参阅解释它的documentationthis article

例如,在您的情况下:

<强> code.py

from subprocess import Popen

def call_something(argument_list):
    binary = '/opt/mybin/'
    Popen([binary] + argument_list)

test.py (假设两个文件都在同一个文件夹中,您需要在测试中修补code.Popen而不是subprocess.Popen

from code import call_something

@mock.patch('code.Popen')
def test_call_something(self, mock_popen):
   binary = '/opt/mybin/'
   args = ['foo', 'bar']
   mock_popen.return_value.returncode = 0
   mock_popen.return_value.communicate.return_value = ('Running', '')

   call_something(args)

self.assertEqual(
    [binary] + args,
    mock_popen.call_args_list
)