Make it so with RSpec Macros
RSpec macros (like those in the fantastic Remarkable library) ease spec writing for repetitive tasks, but is that process more effort than it’s worth? No — it’s actually quite easy to write and include macros for your specs to do some of the standard heavy lifting.
This is a great resource to get started with how to write the actual macros (or custom matchers) themselves.
What tripped me up was how to actually include them in my examples. Monkeypatching is rarely a clean process. And, while the comments on that post mentioned a public API, how to use that API wasn’t immediately obvious (as with many things about RSpec).
In my case, I was looking to define a quick
login! macro that would allow me to easily create a before block to log in as a specified user or just as a FactoryGirl generated one in a TwitterAuth based app. Here’s the module I wrote and stuck in my
module LoginMacro def login!(user=Factory(:user)) before do @current_user = user controller.stub!(:current_user).and_return(@current_user) session[:user_id] = @current_user.id end end end
So that was relatively straightforward and now what I wanted to be able to do was call it in my controller specs like this:
describe UsersController do describe "#create" do login! it 'should etc. etc.' end end
As it turns out, RSpec offers the ability to add macros and matchers via the
config.include methods on the RSpec configuration object (extend is for class-level macros like the one I wrote here, include is for instance-level matchers). You just have to add this to your spec helper’s configuration portion:
Voila! Now your specs will be able to use the
login! macro to set up a user in no time.
Experienced RSpec users are already familiar with this, but I find that certain things can be hard to come across if you don’t already know how to use them. So I thought I’d blog for the benefit of others like me: this is an easy way to use RSpec macros.