Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a RSpec controller macro that can accept arguments defined by let or in a before block?

I use Rails 3 and RSpec 2.6.0.

Not sure if that's possible, but here is what I would like to do:

describe UsersController do
  let(:user) { Fabricate :user }
  describe "GET /user/:id" do
    should_return_401_code_if_user_is_not_confirmed :get, :show, :id => user.id
  end
  describe "PUT /user/:id" do
    should_return_401_code_if_user_is_not_confirmed :put, :update, :id => user.id
  end
end

I tried to implement the macro like this:

module ControllerMacros
  def should_return_401_code_if_user_is_not_confirmed(verb, action, params = {})
    it "returns a 401 code if the user is not an admin" do
      send verb, action, params
      response.code.should == "401"
    end
  end
end

But when running those specs I get the error undefined local variable or method 'user'. I tried to switch to a @user variable defined in a before block, but it does not work either. I suspect it's because I'm not in a example block.

Is it possible to pass to a controller macro arguments defined by let or in a before block?

Thanks!

like image 247
Florent2 Avatar asked Jul 15 '11 01:07

Florent2


1 Answers

From reading through this thread on the rspec-users listserve, it appears the answer is no. The issue is that your let/before vars aren't being initialized until the it block in the body of your macro, so you can't reference them as parameters to the macro call.

I'm trying to do essentially the same thing in a site I'm working on. The solution I'm going with is to call the macro method with a block that will return the params hash you want, and then use instance_eval in the macro body to evaluate the block using the macro's scope.

#spec
...
describe "GET /user/:id" do
  should_return_401_code_if_user_is_not_confirmed :get, :show { {:id => user.id} }
end

#macro
...
def should_return_401_code_if_user_is_not_confirmed(verb, action, &params_block)
  it "returns a 401 code if the user is not an admin" do
    params = instance_eval &params_block
    send verb, action, params
...
like image 111
existentialmutt Avatar answered Oct 01 '22 10:10

existentialmutt