简体   繁体   中英

Python - How to unit-test this method that uses Popen?

I have a function that looks like this:

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

I'm trying to figure out how to unit test code that uses this method so that it doesn't actually hit the filesystem but instead uses fake return data and status codes.

I've seen information on how to mock code that uses popen with communicate(), such as How to unit test a function that uses Popen? , but I haven't been able to figure out how to mock code using popen in this manner.

How can I fake out popen here so that this method can return fake output?

First, I'd rewrite the function more simply. In particular, the with statement is unnecessary, since you are neither opening (nor responsible for closing) 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

Now to test, you just mock Popen and configure p.stdout to be a file-like object with the desired data.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM