Should I Mock Kernel#exit

I don’t know what the right answer is, so any insight would be appreciated. From Googling around, I came across this thread on StackOverflow which talks about Validating exits and aborts in Rspec. I have a few issues with this, namely that I am using shoulda and I don’t want to validate the exit, I want to stop it from happening inside of the test.

I have figured out that rescueing a Kernel#exit with afford the same opportunity to test results so I am not sure if mocking it is necessary. Consider the following code which doesn’t involve mocking:

     class Application
        def thread_cleanup(threads)
            threads.each do |thread|
               thread.kill
            end
            $stderr.puts "Terminating..."
            exit
        end
     end

     # test cases
     class ApplicationTest < Test::Unit::TestCase
         should "kill all threads and exit cleanly" do
           threads = Array.new
           threads.push(Thread.new { sleep }, Thread.new { sleep })
           begin
             Application.thread_cleanup(threads)
           rescue SystemExit => e
             assert_equal 0, e.status
           end
         end
     end

Here we rescue the exit and continue on with the testing. The tests don’t actually exit (which allows the suite to continue) and no mocking of core functionality is required. Is it the better way? I don’t know, but it works.

Posted in Testing. Tags: , . 5 Comments »
  • http://eric.lubow.org Eric Lubow

    Specifically I went for
    Thread.new { sleep }
    because that’s what is in my code. I probably should have changed it for the example, but I didn’t mostly out of laziness.

    I also don’t want to give the misconception that I am against mocking. I just wanted to point out that mocking isn’t always necessary and that one can almost exactly match the code in the tests for the closest.

  • http://twitter.com/jacek_becela Jacek Becela

    why

    threads = Array.new
    threads.push(Thread.new { sleep }, Thread.new { sleep })

    and not

    threads = [Thread.new {}, Thread.new {}]

    ?

    I would say mocking is not as bad as heavy monkey-patching stuff to make normal code work. Mocking is actually cool 😉 Now the question is what would I prefer: an exact check of #exit call or the fact of raising exception (which is byproduct of #exit)… In this simple example I would go with mocking for readability.

  • Pingback: Tweets that mention Should I Mock Kernel#exit | Erics Tech Blog -- Topsy.com

  • http://www.nakitoyun.com Oylesinetakilmaca

    nice conversation.but ? think you must change it for the exmaple 🙂

  • Michael Wade

    Nice conversation.