The maze book for programmers!
mazesforprogrammers.com

Algorithms, circle mazes, hex grids, masking, weaving, braiding, 3D and 4D grids, spheres, and more!

DRM-Free Ebook

The Buckblog

assorted ramblings by Jamis Buck

Dereferencing fixtures

26 February 2007 — 1-minute read

I frequently find myself writing a lot of helper methods for my tests. (I think I picked up that habit from Marcel Molina, Jr., actually.) These helper methods encapsulate tasks that I wind up doing all over the place, things like logging in a user, or uploading a file.

However, sometimes I want to pass in a symbol identifying the fixture that should be used in the helper, and sometimes I want to pass a record in directly. To accommodate this, I’ve been using the following idiom in my helpers:

1
2
3
4
def login!(user)
  user = users(user) if Symbol === user
  ...
end

It just checks the argument, and if it is a Symbol, it dereferences it using the “users” method provided by the fixtures.

To make this idiom reusable, I’ve got this little gem in my test_helper.rb file:

1
2
3
4
5
6
7
def dereference(argument, collection)
  if Symbol === argument
    return send(collection, argument)
  else
    return argument
  end
end

The login! method would then be written like this:

1
2
3
4
def login!(user)
  user = dereference(user, :users)
  ...
end

It’s a little thing, but it sure makes those test helpers a lot more flexible!

Reader Comments

I prefer

class Symbol def dereference(collection) collection.send(self) end end class Object def dereference(collection) self end end

Class comparisons in conditional code raises the hairs on the back of my head :)

Gah! Comment preview would be handy…

Jamis,

I’m not clear on why you need to type-check the “user” parameter in the login! method. Wouldn’t it throw an error if you tried using something that’s not a symbol, alterting you so you could fix it?

I’m sure I’m missing something obvious, but it seemed to me that if you were planning on sending symbols as the parameter in all cases, would you need to type-check it? Would you write a test that sent a non-symbol to that method on purpose?

Thanks,

Jeff

Jamis,

Talking to yourself again? :)

Love the site, keep up the good work.

Jeff, the idea is that you could then do something like the following:

1
2
3
4
5
6
7
8
9
10
def test_new_user_login
  user = User.new(...)
  login!(user)
  ...
end

def test_existing_user_login
  login!(:jamis)
  ...
end

In other words, I could pass either a real activerecord instance to the login! method, or I could pass a symbol identifying the fixture load. I could even pass a mock object in if I wanted, since it only tests on whether the parameter is a symbol or not.

Note that login! is NOT a method in the application itself; it is a method in the test harness, used to setup some condition for subsequent tests.

Jamis,

That makes sense! I didn’t think about branching in the helper, based on whether you send it a record or a symbol. I was thinking it was just for error-checking, which would be a bit redundant.

Thanks!

Jeff

By the way, I have no idea why I wrote your name on my last comment, Jamis! :)

Jeff