Skip to content

Instantly share code, notes, and snippets.

@jeremyw
Created September 29, 2012 21:25
Show Gist options
  • Save jeremyw/3805223 to your computer and use it in GitHub Desktop.
Save jeremyw/3805223 to your computer and use it in GitHub Desktop.
Testing Rails 4 strong parameters
class AccountsController < ApplicationController
def update
@account = Account.find(params[:id])
respond_to do |format|
if @account.update_attributes(account_params)
format.html { redirect_to @account, notice: 'Account was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
private
def account_params
# note that the Account#name attribute is permitted, but Account#balance is not
params.require(:account).permit(:name)
end
end
require 'spec_helper'
describe AccountsController do
describe "PUT update" do
describe "with forbidden params" do
let(:account) { Account.create! balance: 100.0, name: 'Checking' }
it "does not update the forbidden params" do
put :update,
id: account.to_param,
account: { 'name' => 'Savings', 'balance' => '1000000' }
assigns(:account).name.should eq('Savings') # explicitly permitted
assigns(:account).balance.should eq(100.0) # implicitly forbidden
response.should redirect_to account
end
end
end
end

This is a simple example of strong parameters in Rails (Rails 4 or Rails 3.2 with the strong_parameters gem). The test demonstrates that the Account's name attribute can be updated via the update action, but its balance cannot. The system works.

However, how far should we take these kinds of tests? Now that we've moved this responsibility from the model to the controller, should we invest in controller specs/tests to:

  1. ensure that all permitted attributes can be updated?
  2. ensure that any forbidden attributes cannot be updated?

Is there a good, clean, expressive way to test the private account_params method in the controller, to verify the contents of the whitelist rather than the effects of the whitelist? I've used shoulda-style "should(_not) allow_mass_assignment_of" macros in the past. There doesn't appear to be anything analogous for strong_parameters yet.

@jeremyw
Copy link
Author

jeremyw commented Sep 29, 2012

@freerobby Good point, I absolutely do not want to test Rails in my app's tests. The expectation syntax is pretty noisy and not very expressive, but a little DSL/macro could wrap it pretty easily I think.

@silverdr
Copy link

Hello, would it be possible to update this for Rails 5, and its 'test_helper'?

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