模拟 subprocess.Popen 而不执行

jdb*_*org 2 python subprocess mocking python-unittest

我正在尝试为调用subprocess.Popen. 我只想测试arg发送到的参数Popen是否符合预期。我其实不想Popen跑。在不嘲笑arg列表的情况下这可能吗?

例如

def call_something(argument_list):
    binary = '/opt/mybin/'
    Popen([binary] + argument_list)
Run Code Online (Sandbox Code Playgroud)

然后,进行测试。

@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
    )
Run Code Online (Sandbox Code Playgroud)

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

小智 6

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

请参阅文档这篇文章,对其进行了很好的解释。


例如,在您的情况下:

代码.py

from subprocess import Popen

def call_something(argument_list):
    binary = '/opt/mybin/'
    Popen([binary] + argument_list)
Run Code Online (Sandbox Code Playgroud)

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
)
Run Code Online (Sandbox Code Playgroud)