Dereferencing fixtures
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 :)
26 Feb 2007
Gah! Comment preview would be handy…
26 Feb 2007
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
26 Feb 2007
Jamis,
Talking to yourself again? :)
Love the site, keep up the good work.
26 Feb 2007
Jeff, the idea is that you could then do something like the following:
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.
26 Feb 2007
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
26 Feb 2007
By the way, I have no idea why I wrote your name on my last comment, Jamis! :)
Jeff
27 Feb 2007