如何指定退出或中止的方法
我有一个从CLI触发的方法,它有一些明确退出或中止的逻辑路径。 我发现在为此方法编写规范时,RSpec将其标记为失败,因为退出是exception。 这是一个简单的例子:
def cli_method if condition puts "Everything's okay!" else puts "GTFO!" exit end end
我可以使用should raise_error(SystemExit)
将规范包装在lambda中,但是忽略了块内发生的任何断言。 要明确:我不是在测试退出本身,而是在它之前发生的逻辑。 我该如何选择这种方法呢?
只需将断言放在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
当我运行rspec时,它正确告诉我:
expected: :logics got: :bad_logic (using ==)
有什么情况对你不起作用吗?
编辑:我在lambda中添加了一个’exit’调用来处理logic_and_exit
没有退出的情况。
编辑2:更好的是,只需在测试中执行此操作:
begin @foo.logic_and_exit rescue SystemExit end @foo.result.should == :logics
覆盖Rspec 3期望语法的新答案。
测试输出
只是为了测试你真正想要的东西(即你没有测试exception或值响应),输出到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
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
请注意, output("String").to_...
可以接受正则Regex
例如。
output(/^Everything's okay!$/).to_stdout
它也可以从stderr
捕获,例如。
output("GTFO").to_stderr
(对于OP的例子,这将是一个更好的发送它的地方。)
测试退出
您可以单独测试false条件也会引发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
我可以使用raise_error(SystemExit)将规范包装在lambda中,但是忽略了块内发生的任何断言。
我认为将测试放在lambda内部或外部没有区别。 在任何一种情况下,失败消息都有点神秘:
def cli_method(condition) if condition puts "OK" else puts "GTFO" exit end end describe "cli_method" do context "outside lambda" do # passing it "writes to STDOUT when condition is false" do STDOUT.should_receive(:puts).with("GTFO") lambda { cli_method(false) }.should raise_error(SystemExit) end # failing it "does not write to STDOUT when condition is false" do STDOUT.should_not_receive(:puts).with("GTFO") lambda { cli_method(false) }.should raise_error(SystemExit) end end context "inside lambda" do # passing it "writes to STDOUT when condition is false" do lambda { STDOUT.should_receive(:puts).with("GTFO") cli_method(false) }.should raise_error(SystemExit) end # failing it "does not write to STDOUT when condition is false" do lambda { STDOUT.should_not_receive(:puts).with("GTFO") cli_method(false) }.should raise_error(SystemExit) end end end # output .FF Failures: 1) cli_method outside lambda does not write to STDOUT when condition is false Failure/Error: lambda { expected SystemExit, got #).puts("GTFO") expected: 0 times received: 1 time> # ./gtfo_spec.rb:23:in `block (3 levels) in ' 2) cli_method inside lambda does not write to STDOUT when condition is false Failure/Error: lambda { expected SystemExit, got #).puts("GTFO") expected: 0 times received: 1 time> # ./gtfo_spec.rb:39:in `block (3 levels) in '