RSpec - 如何复合匹配器 raise_error 和 output.to_stdout?

Dan*_*n R 5 ruby rspec thor

我有一个基于 Thor 的 ruby​​ CLI 项目,我正在尝试向其中添加单元测试。它最初是一个宠物项目,现在在内部相当大且重要。不管怎样,我从来没有真正开始过单元测试,只是移植到现有的例子上,所以当谈到 rspec 时我是一个菜鸟。

我从一个相当基本的示例开始,确保如果我给它一个不存在的文件,它会回复一个解释性错误并退出。

以下是我尝试将它们复合的方法:

context 'with incorrect filename' do
  it 'should fail cleanly' do
    expect do
      subject.format('bad_file_name')
    end.to output('   ERROR  Unable to load file bad_file_name, exiting...').to_stdout.and raise_error(SystemExit)
  end
end
Run Code Online (Sandbox Code Playgroud)

它可以工作,但不能在这里正确捕获标准输出输出..也尝试过:

context 'with incorrect filename' do
  it 'should fail cleanly' do
    expect do
      expect do
        subject.format('fixtures/invalid.yaml')
      end.to output('   ERROR  Unable to load file bad_file_name, exiting...').to_stdout
    end.to raise_error(SystemExit)
  end
end
Run Code Online (Sandbox Code Playgroud)

看起来它是有效的,除了(如本例所示)它实际上并没有测试输出,因为输出不匹配。

那么同时检查引发的错误和标准输出的输出的正确方法是什么?

aus*_*man 5

这对我有用

expect { whatever }.to output('stderr message').to_stderr
                   .and output(Regexp.new('stdout message')).to_stdout
                   .and raise_error('Error message')
Run Code Online (Sandbox Code Playgroud)