Python - 如何对使用Popen的方法进行单元测试?

时间:2017-02-13 19:46:56

标签: python unit-testing mocking python-unittest

我有一个看起来像这样的函数:

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以便此方法可以返回假输出?

1 个答案:

答案 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"]