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.
