我有一个看起来像这样的函数:
def run_shell_command_return_output(command_array):
output = []
p = Popen(command_array, stdout=PIPE, bufsize=1)
with p.stdout:
for line in iter(p.stdout.readline, b''):
output.append(line.decode('utf8').strip())
p.wait()
return output
我试图弄清楚如何对使用此方法的代码进行单元测试,以便它实际上不会触及文件系统,而是使用虚假的返回数据和状态代码。
我已经看过有关如何模拟使用popen和communication()的代码的信息,例如How to unit test a function that uses Popen?,但我还没有能够弄清楚如何使用popen模拟代码这种方式。
如何在这里伪装popen以便此方法可以返回假输出?
答案 0 :(得分:1)
首先,我会更简单地重写这个功能。特别是,with
语句是不必要的,因为您既不打开(也不负责关闭)p.stdout
。
def run_shell_command_return_output(command_array):
output = []
p = Popen(command_array, stdout=PIPE, bufsize=1)
for line in p.stdout:
output.append(line.decode('utf8').strip())
# I think the wait is redundant, since reads on p.stdout
# would block if p is still running.
p.wait()
return output
现在进行测试,您只需模拟Popen
并将p.stdout
配置为具有所需数据的类文件对象。
with mock.patch('Popen') as mock_popen:
mock_popen.return_value.stdout = io.StringIO("data\ndata\ndata\n")
output = run_shell_command_return_output(["what", "ever"])
assert output == ["data", "data", "data"]