[rspec-users] Specing exit codes

Scott Taylor mailing_lists at railsnewbie.com
Sun Oct 7 02:26:53 EDT 2007


On Oct 6, 2007, at 11:31 PM, Mikel Lindsaar wrote:

> I am writing a small ruby script that will be accepting input from
> postfix's pipe command (ie, not running via the shell, directly
> executing).
>
> One of the things I need to do it spec the exit codes to make sure I
> am returing the correct exit codes for each condition as Postfix will
> then return SMTP errors as appropriate.
>
> I have two files that concern this bit of the program, init.rb and  
> init_spec.rb.
>
> init.rb right now looks like this:
> ------------------------
> class Init
>   exit 1
> end
> ------------------------
>
> init_spec.rb looks like this:
> ------------------------
> require 'spec'
> require 'systemu'
> require 'init'
>
> describe Init do
>   it "should exit on status code 1 without parameters"
>     command = "ruby mail_dump/init.rb" # not portable
>     status, stdout, stderr = systemu command
>     status.should == # what do I put here?
>   end
> end
> ------------------------
>
> I have tried a number of things, from trying to stub exit to aliasing
> kernel.exit to something else and replacing it... all without joy.
>
> The spec runs and hits the "exit 1" in init.rb and does what it is
> mean to do... exit.  But that also exits RSpec and so the test is
> never run!
>
> The only thing I found DID work is if I alias Kernel.exit inside the
> init.rb file to "real_exit" and then redefine Kernel exit like so:
>
> class Object
>   module Kernel
>     alias real_exit exit
>     def exit(arg)
>       return true if arg == 1
>     end
>   end
> end
>
> and then test exit by mocking it and making sure it returns true...
> but a spec that has to modify the test code isn't going to scale too
> well... and this doesn't seem right.
>
> Has anyone else had this problem?  How did you solve it?

I had a similar problem a while back.  Aslak tipped me off to  
dependency injection.  Something like this:

describe Init do
   before :each do
     @kernel = mock(Kernel)
     @kernel.stub!(:exit).and_return 1
   end

   it "should exit on status code 1 without parameters"
     init = Init.new(@kernel)
     init.start
     init.status.should == 1
   end
end

module Init
   def start(kernel=Kernel)
     kernel.start
   end
end


Scott



More information about the rspec-users mailing list