Using RSpec to Test system calls with %x and backticks (grave accents)

by Clayton on February 25, 2009

I’ve been working on a project that requires a call to the shell from inside a controller. I knew that I would need the output of the shell command, in this case a rake task, so that I could display the result to the user. However, when I went to implement the spec, I wasn’t sure how to setup the expectation.

Our Controller

1
2
3
4
5
6
7
8
InfoController < ApplicationController
 
  def index
    flash[:notice] = `cat /home/clayton/info` # sets the notice to "clayton@lengelzigich.com"
    redirect to people_url
  end
 
end

Our Spec

1
2
3
4
5
6
7
8
describe InfoController do
  describe "index" do
    it "should set the contents of the flash notice to clayton's contact info" do
      controller.should_receive(:'`').with("cat /").and_return("clayton@lengelzigich.com")
      get :index
    end
  end
end

The important part of the spec is line 43. We tell the controller to expect a call to '`' with our shell command and return the contents of the file. The '`':, backtick1, is a method in the Kernel class2. It is also possible to use @%x@ to run commands in the shell from ruby, the two are the same.

`cat /etc/motd`
# is the same as
%x[cat /etc/motd]

If you are using %x@, and need a way to write a spec, consider changing @%x to @“@ and using the above approach.

1 Some people call backticks “grave accents”, some people are dumb.

2 The @`@ method that comes from Kernel isn’t actually called on the Kernel class, it’s mixed into your Object at run time. Or so I’ve read.

3 Some credit for this discovery goes to my straight up ballin’ pair.

Leave a Comment

Previous post:

Next post: