Testing invocation of external executables, %x{}, `

If you ever found yourself trying to write tests for code that invokes an external executable, such as:

  class Beef < ActiveRecord::Base
    def diskspace(flags = 'sh')
      `du -#{flags} .`.split.first

…and wondered how to write a spec that ensures the du command is called with the right options, you might have tried something like:

  before do
    @beef = Beef.new

  it "has diskspace with humanized multipliers" do
    Kernel.should_receive(:`).with("du -h .")

That doesn’t work.

After some headscratching and calls for help on the ruby-talk mailing list, I learned how the Kernel#` method is not being called directly. The Ruby object hierarchy has Object at the top-level, and thus all your objects eventually descends from Object. As Object mixes in Kernel, all your objects have all the methods defined in that module, so it’s not Kernel that receives your call to “`”, but it’s the current ‘self’. In the example above it’s the @beef instance.


  class Sheep
    def mytick(arg)
      puts "tickety-tick: #{arg.inspect}"
    alias :"`" :mytick

    def tick_it!


  $ ruby sheep.rb
  tickety-tick: "cheese"

So, to test the original code, here’s the right way:

  it "has diskspace with humanized multipliers" do
    @beef.should_receive(:`).with("du -h .")

All of the above also applies to the “%x[]”-syntax (just an alias for Kernel#`).

Kudos to Brian Chandler for helping out on this, and happy hacking!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.