如何规范退出或中止的方法

Jim*_*dra 10 ruby rspec

我有一个从CLI触发的方法,它有一些明确退出或中止的逻辑路径.我发现在为此方法编写规范时,RSpec将其标记为失败,因为退出是异常.这是一个简单的例子:

def cli_method
  if condition
    puts "Everything's okay!"
  else
    puts "GTFO!"
    exit
  end
end
Run Code Online (Sandbox Code Playgroud)

我可以将规范包装在lambda中should raise_error(SystemExit),但是忽略了块内发生的任何断言.要明确:我不是在测试退出本身,而是在它之前发生的逻辑.我该如何选择这种方法呢?

Dav*_*son 6

只需将断言放在lambda之外,例如:

class Foo
  attr_accessor :result

  def logic_and_exit
    @result = :bad_logic
    exit
  end
end

describe 'Foo#logic_and_exit' do
  before(:each) do
    @foo = Foo.new
  end

  it "should set @foo" do
    lambda { @foo.logic_and_exit; exit }.should raise_error SystemExit
    @foo.result.should == :logics
  end
end
Run Code Online (Sandbox Code Playgroud)

当我运行rspec时,它正确告诉我:

expected: :logics
     got: :bad_logic (using ==)
Run Code Online (Sandbox Code Playgroud)

有什么情况对你不起作用吗?

编辑:我在lambda中添加了一个'exit'调用来处理logic_and_exit不退出的情况.

编辑2:更好的是,只需在测试中执行此操作:

begin
  @foo.logic_and_exit
rescue SystemExit
end
@foo.result.should == :logics
Run Code Online (Sandbox Code Playgroud)


oco*_*odo 6

覆盖Rspec 3期望语法的新答案.

测试输出

只是为了测试你真正想要的东西(即你没有测试异常或值响应),输出到STDOUT的是什么.

什么时候condition是假的

it "has a false condition" do
  # NOTE: Set up your condition's parameters to make it false
  expect {
    begin cli_method
    rescue SystemExit
    end
  }.to output("GTFO").to_stdout # or .to_stderr
end
Run Code Online (Sandbox Code Playgroud)

什么时候condition是真的

it "has a true condition" do
  # NOTE: Set up your condition's parameters to make it true
  expect {
    begin cli_method
    rescue SystemExit
    end
  }.to output("Everything's okay!").to_stdout
end
Run Code Online (Sandbox Code Playgroud)

注意,output("String").to_...可以接受Regex例如.

output(/^Everything's okay!$/).to_stdout
Run Code Online (Sandbox Code Playgroud)

它也可以从stderr例如捕获.

output("GTFO").to_stderr
Run Code Online (Sandbox Code Playgroud)

(对于OP的例子,哪个是发送它的更好的地方.)

测试退出

您可以单独测试虚假条件也会提升 SystemExit

it "exits when condition is false" do
  # NOTE: Set up your condition's parameters to make it false
  expect{cli_method}.to raise_error SystemExit
end

it "doesn't exit when condition is true" do
  # NOTE: Set up your condition's parameters to make it true
  expect{cli_method}.not_to raise_error SystemExit
end
Run Code Online (Sandbox Code Playgroud)