RoR Testing - One Thing To Do (I think) And One Thing Not To Do (I'm Sure)

Jul 19, 2011

This is gonna be quick. I've come across two patterns in my Ruby/Rails testing that I think are worth mentioning.

The first, which I think (but have some doubts) is good, revolves around testing with dependencies and their return values. As a simple example, we might have the following code:

def index
 user = User.find_by_id(params[:id])
 render :json => {:user => user}

Now, I'm still a believer that when we are dealing with interactions between modules, it is vital to minimize the brittleness by not over specifying details. If we write a test to verify that we output the proper result, I believe it is OK to lean on ruby's dynamism:

it "should return the found user" do
  User.stub!(:find_by_id).and_return("dynamic typing is over 9000!")
  get :index
  json = ActiveSupport::JSON.decode(response.body)
  json['user'].should == 'dynamic typing is over 9000!'

See what I did? I leveraged the fact that find_by_id can return any type, and just kept my test simple. Now, this might not be the best example, because testing that a user instance properly serializes isn't a bad idea. But hopefully you get the picture. This might not be the normal way that you write tests, but I think it has a place when used judiciously.

The other thing, which has caused me a bit of hassle, is to test Rails controllers and passing non-string parameters. Sticking with the above example, I might do:

get :index, {:id => 9002}
but I really should be doing:
get :index, {:id => '9002'}

This is a very bad oversight, and it's worth using some type of helper to make sure you are only passing in string values.