2009-09-26 9 views
36

मैं कमांड लाइन तर्कों के लिए व्यवहार करने की कोशिश कर रहा हूं, मेरी स्क्रिप्ट यह सुनिश्चित करने के लिए प्राप्त करती है कि सभी सत्यापन पास हो जाएं। मेरे कुछ कमांड लाइन तर्कों के परिणामस्वरूप abort या exit का आह्वान किया जाएगा क्योंकि आपूर्ति किए गए पैरामीटर गुम या गलत हैं।मैं आरएसपीईसी में निकास और बंदरगाहों को कैसे मान्य कर सकता हूं?

मैं कुछ इस तरह जो काम नहीं कर रहा कोशिश कर रहा हूँ:

# something_spec.rb 
require 'something' 
describe Something do 
    before do 
     Kernel.stub!(:exit) 
    end 

    it "should exit cleanly when -h is used" do 
     s = Something.new 
     Kernel.should_receive(:exit) 
     s.process_arguments(["-h"]) 
    end 
end 

exit विधि सफाई से फायरिंग परीक्षण सत्यापित होने से रोक रहा है RSpec (": बाहर निकलने के SystemExit" मैं मिलता है)।

मैंने mock(Kernel) पर भी कोशिश की है, लेकिन यह भी काम नहीं कर रहा है जैसा कि मुझे पसंद है (मुझे कोई स्पष्ट अंतर नहीं दिख रहा है, लेकिन ऐसा इसलिए है क्योंकि मुझे यकीन नहीं है कि कर्नेल को कैसे नकल करना है और मजाक करना सुनिश्चित करें कर्नेल का उपयोग मेरे Something वर्ग में किया जाता है)।

उत्तर

25

इस कोशिश:

module MyGem 
    describe "CLI" do 
    context "execute" do 

     it "should exit cleanly when -h is used" do 
     argv=["-h"] 
     out = StringIO.new 
     lambda { ::MyGem::CLI.execute(out, argv) }.should raise_error SystemExit 
     end 

    end 
    end 
end 
+0

चेतावनी: हम एक ऐसी ही समाधान के साथ समस्या नहीं थी क्योंकि RSpec शायद 'exit's जब उम्मीदों असफल है, तो हम ऊपर हमारे अपने आदि के बजाय बचाव RSpec के' exit's हो सकते हैं –

2

खोदने के बाद, I found this

# something.rb 
class Something 
    def initialize(kernel=Kernel) 
     @kernel = kernel 
    end 

    def process_arguments(args) 
     @kernel.exit 
    end 
end 

# something_spec.rb 
require 'something' 
describe Something do 
    before :each do 
     @mock_kernel = mock(Kernel) 
     @mock_kernel.stub!(:exit) 
    end 

    it "should exit cleanly" do 
     s = Something.new(@mock_kernel) 
     @mock_kernel.should_receive(:exit) 
     s.process_arguments(["-h"]) 
    end 
end 
16

जवाब मार्कस के लिए धन्यवाद

मेरे समाधान इस तरह देख समाप्त हो गया। एक बार जब मुझे यह सुराग मिल गया तो मैं भविष्य के उपयोग के लिए एक अच्छा मैचर रख सकता था।

RSpec::Matchers.define :exit_with_code do |exp_code| 
    actual = nil 
    match do |block| 
    begin 
     block.call 
    rescue SystemExit => e 
     actual = e.status 
    end 
    actual and actual == exp_code 
    end 
    failure_message_for_should do |block| 
    "expected block to call exit(#{exp_code}) but exit" + 
     (actual.nil? ? " not called" : "(#{actual}) was called") 
    end 
    failure_message_for_should_not do |block| 
    "expected block not to call exit(#{exp_code})" 
    end 
    description do 
    "expect block to call exit(#{exp_code})" 
    end 
end 
3

इसकी सुंदर नहीं है, लेकिन मैं इस का उपयोग कर:

it "should exit cleanly when -h is used" do 
    lambda { ::MyGem::CLI.execute(StringIO.new, ["-h"]) }.should exit_with_code(0) 
end 
it "should exit with error on unknown option" do 
    lambda { ::MyGem::CLI.execute(StringIO.new, ["--bad-option"]) }.should exit_with_code(-1) 
end 

इस मिलान का उपयोग करने के अपने पुस्तकालयों या कल्पना-सहायकों में जोड़ना

begin 
    do_something 
rescue SystemExit => e 
    expect(e.status).to eq 1 # exited with failure status 
    # or 
    expect(e.status).to eq 0 # exited with success status 
else 
    expect(true).eq false # this should never happen 
end 
12

नए का उपयोग करना आरएसपीसी वाक्यविन्यास:

expect { code_that_exits }.to raise_error(SystemExit) 

अगर कुछ ething STDOUT करने के लिए मुद्रित है और आप वह भी परीक्षण करना चाहते हैं, तो आप की तरह कुछ कर सकते हैं:

context "when -h or --help option used" do 
    it "prints the help and exits" do 
    help = %Q(
     Usage: my_app [options] 
     -h, --help      Shows this help message 
    ) 

    ARGV << "-h" 
    expect do 
     output = capture_stdout { my_app.execute(ARGV) } 
     expect(output).to eq(help) 
    end.to raise_error(SystemExit) 

    ARGV << "--help" 
    expect do 
     output = capture_stdout { my_app.execute(ARGV) } 
     expect(output).to eq(help) 
    end.to raise_error(SystemExit) 
    end 
end 

कहाँ capture_stdout रूप Test output to command line with RSpec में देखा परिभाषित किया गया है।

अद्यतन: का उपयोग कर RSpec's output matchercapture_stdout के बजाय

+4

वहाँ भी है एक अंतर्निहित 'आउटपुट' मैचर: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/output-matcher –

+0

@ जेरेडबेक टिप्पणी के लिए धन्यवाद। मैंने हाल ही में सिस्टम कमांड के आउटपुट को कैप्चर करने के लिए आरएसपीसी की 'output_to_stdout_from_any_process' matcher का उपयोग किया था और हालांकि यह डिस्क I/O की वजह से धीमा है, यह अच्छी तरह से काम करता है। – Dennis

1

मैं समाधान @Greg नए वाक्य रचना आवश्यकताओं के कारण प्रदान की अद्यतन करने के लिए किया था पर विचार करें।

RSpec::Matchers.define :exit_with_code do |exp_code| 
    actual = nil 
    match do |block| 
    begin 
     block.call 
    rescue SystemExit => e 
     actual = e.status 
    end 
    actual and actual == exp_code 
    end 
    failure_message do |block| 
    "expected block to call exit(#{exp_code}) but exit" + 
     (actual.nil? ? " not called" : "(#{actual}) was called") 
    end 
    failure_message_when_negated do |block| 
    "expected block not to call exit(#{exp_code})" 
    end 
    description do 
    "expect block to call exit(#{exp_code})" 
    end 
    supports_block_expectations 
end 
संबंधित मुद्दे

 संबंधित मुद्दे