模拟 subprocess.Popen 而不执行
Mocking subprocess.Popen without executing
我正在尝试为调用 subprocess.Popen
的方法编写单元测试。我想要测试的是发送到 Popen
的 arg
参数是否符合预期。我实际上并不想要 Popen
到 运行。如果不模拟 arg
列表,这可能吗?
例如
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
是空的。
使用mock.patch
时必须指向导入的对象
参见 documentation and this 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
)
我正在尝试为调用 subprocess.Popen
的方法编写单元测试。我想要测试的是发送到 Popen
的 arg
参数是否符合预期。我实际上并不想要 Popen
到 运行。如果不模拟 arg
列表,这可能吗?
例如
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
是空的。
使用mock.patch
时必须指向导入的对象
参见 documentation and this 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
)