14

I am using the strong_parameters gem in my controllers, but I'm having a hard time understanding how I would test it.

Here's an example of my setup

class UserController < ActionController::Base
  include ActiveModel::ForbiddenAttributesProtection

  def create
    @user = User.new(user_params)
    if @user.save
      ...
    end
  end

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :username, :email)
  end
end

I want to test the user_params method to make sure that it is correctly filtering out malicious key/value pairs, but can't figure out how to do it. Has anyone else been through this?

3 Answers 3

17

You can stub the params hash as

params = ActionController::Parameters.new(your_hash)

This is the class that your URL params are being converted to in your controller, and it gives you the require and permit methods.

I personally extract the functionally out into a new class to handle the authorization policy.

Sign up to request clarification or add additional context in comments.

Comments

6

Modify this according to your need,

describe "create action" do
    it 'creates a user' do
      User.should_receive(:create).
        with({name: 'Alan D'}.with_indifferent_access)
      post :create, user:
        { first_name: 'Alan', last_name: 'Donald', username: 'alan77', email: '[email protected]' }
    end
end

or other alternative solution to this problem is:

describe UsersController::UserParams do
  it 'cleans the params' do
    params = ActionController::Parameters.new(user: {foo: 'bar', name: 'baz'})
    user_params = UsersController::UserParams.build(params)
    expect(user_params).to eq({name: 'baz'}.with_indifferent_access)
  end
end

Comments

0

I'm not sure I would test strong_parameters, which I am guessing you're using via the gem.

The gem has its own tests, so we can assume it works as expected.

This is an example of 'testing Rails', which I believe is unnecessary. I wouldn't test that attr_accessible works as advertised (Testing Rails), or attr_accessor (Testing Ruby).

IMHO, your integration tests should cover all desired instances of success/failure and implicitly cover your strong_parameter configuration.

4 Comments

Our test policy is to explicitly write tests for all functionality, to allow us to potentially switch gems/roll our own later on and still know that the system is working.
You can also be testing that your code that integrates in with strong_parameters is working properly. I have fields which are writable/not writeable depending on user roles/permissions, so I need to test that these two pieces integrate properly.
Having taken an app from Rails 1.1 to 3.2 (and now preparing for 4.0), I can assure you that testing Rails is very necessary. Something that worked one way in one version of Rails may change behavior in another version. For instance, I used to clone activerecord records using the clone method, but somewhere between 3.0 and 3.2 they decided that dup would provide that functionality instead... and do it slightly differently. This was not well advertised, but it was quickly caught by my tests.
Yes @sockmonk - this is definitely one situation where you'd want to test Rails :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.