Skip to content

Instantly share code, notes, and snippets.

@dimitarvp
Created April 2, 2014 23:07
Show Gist options
  • Save dimitarvp/9945140 to your computer and use it in GitHub Desktop.
Save dimitarvp/9945140 to your computer and use it in GitHub Desktop.
Cannot modify `request.params` in before(:all) block.
# Given this auth helper in spec/support/ directory...
module AuthHelpers
def add_token_to_params(token)
request.params.merge!({sessionToken: token}) # also tried 'request.params[:sessionToken] = token'
end
end
# Given this test...
class ThingController
describe Thing do
before(:all) do
@user = User.authenticate(Settings.tests.user, Settings.tests.password)
@token = @user.attributes["sessionToken"]
end
describe "attempt to create Thing without session token" do
before(:each) { add_token_to_params(@token) } # Yes, I did inspect it here, the @token has a valid value. ;)
it "should fail" do
puts request.params # Shows {"sessionToken"=>"abc"}
post :create, attr1: 1, attr2: 'abc' # etc.
puts request.params # Shows {"attr1"=>1, "attr2"=>"abc"}
# failure here; my application_controller before_filter that enforces the presence of
# the 'sessionToken' parameter kicks in and returns '401 Unauthorized'.
response.should be_success
end
end
end
end
# ...I want to freely modify request parameters before invoking controller actions.
# (I know I can modify the headers, btw; tried it and it works.)
# I am 99% certain I am doing it the wrong way, but couldn't find anything in Google
# that actually covers my requirements.
# The problem is not just to make this work in one "it" block; I have dozens of mini tests.
# I know I can make this work using simpler methods for just one "it" block, but that's not my scenario.
@cupakromer
Copy link

In general, for controller specs, you don't access request directly. I checked my work projects and the only time we touch request is to mess with the env or headers for it.

The params are set on the call to get, post, put, etc. So here line 21: https://gist.github.com/dimitko/9945140#file-test-rb-L21. That's setting the params to attr1: 1, attr2: 'abc'.

I see two options here:

  1. Use post :create, request.params
  2. Change the helper to be more robust.

Personally I'd go with option 2. Often I have different names for params in different specs. Option 2 gives me the most flexibility in my code choices.

module AuthHelpers
  def add_token_to(params, token)
    params.merge!({sessionToken: token})
  end
end

# Given this test...
class ThingController
  describe Thing do
    before(:all) do
      @user = User.authenticate(Settings.tests.user, Settings.tests.password)
      @token = @user.attributes["sessionToken"]
    end

    describe "attempt to create Thing without session token" do
      let(:a_specific_type_of_params) { {attr1: 1, attr2: 'abc'} }
      before(:each) do
        add_token_to(a_specific_type_of_params, @token)
      end

      it "should fail" do
        post :create, a_specific_type_of_params
        response.should be_success
      end
    end
  end
end

@dimitarvp
Copy link
Author

That did it. I am just not that well familiarized with the RSpec lingo yet. Thanks a lot for your support, it's highly appreciated. =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment