如何使用RSpec测试子进程的输出

时间:2016-02-23 14:37:06

标签: ruby shell rspec

我想测试echo 1输出1,但

expect { `echo 1` }.to output("1").to_stdout

不起作用。它表示它不会向stdout输出任何内容,而

expect { print 1 }.to output("1").to_stdout

工作得很好。为什么第一个不起作用?

1 个答案:

答案 0 :(得分:4)

expect { `echo 1` }.to output("1").to_stdout

不起作用有两个原因:

  1. echo在子流程中运行。 RSpec的output匹配器默认不处理子进程的输出。但您可以使用to_stdout_from_any_process而不是to_stdout来处理子进程,尽管速度稍慢。

  2. output仅适用于发送到与Ruby进程相同的标准输出流的输出。反引号打开一个新的标准输出流,将命令的标准输出发送给它,并在命令完成时返回流的内容。我不认为你是否关心是用反引号还是其他方式运行子进程,所以只需使用system(将命令的标准输出发送到Ruby进程的标准输出流)。

  3. 解决这两点给了我们这个期望,通过了:

    expect { system("echo 1") }.to output("1\n").to_stdout_from_any_process
    

    (我必须更改它的预期值,因为echo添加换行符。)

    正如MilesStanfield指出的那样,在你给它的情况下等同且更容易测试反引号的输出而不是使用output

    expect { `echo 1` }.to eq "1\n"
    

    在您可能想到的更复杂的情况下,这可能会或可能不会起作用。