2014-06-18 53 views
10

用Rspec測試Rails控制器中強參數過濾的實際策略是什麼? (除了應該匹配者)如何編寫失敗的測試,然後使其綠色?如何用Rspec測試強參數?

+0

我的回答有幫助嗎?也許我可以澄清一些事情。 – zishe

+0

謝謝你,你真的幫了我。我不知道with_indifferent_access。以及如何測試屬性需求,如params.require:user? – Molfar

回答

9

用期望和所有(不滿意)參數創建2個散列。然後將所有參數傳遞給行爲,並檢查您是否對象模型只接收預期的參數。如果你不使用強參數過濾器,它不會。比添加params權限並再次檢查測試。

例如,這樣的:

# action 
def create 
    User.create(params) 
end 

# spec 
it 'creates a user' do 
    expect_any_instance_of(User).to receive(:create). 
    with({name: 'Sideshow Bob'}.with_indifferent_access) 
    post :create, user: 
    { first_name: 'Sideshow', last_name: 'Bob', name: 'Sideshow Bob' } 
end 

將通過所有PARAMS到用戶和測試將失敗。並且當你過濾它們時:

def user_params 
    params.require(:user).permit(:name) 
end 

和更改動作與User.create(user_params),測試將通過。

+2

'create'是在'ActiveRecord :: Base'上定義並由'User'繼承的類級方法。因此,雖然'expect_any_instance(User)'(對'User'實例的模擬期望)_might_ work,'expect(User)'(對'User'類的模擬期望)也可以工作,並且更加簡單。 – dleve123

2

這是我如何做的:

describe 'Safe Params' do 

    let(:mixed_params) { 
    { 
     blueprint_application_environment: { 
     id: 1000, 
     blueprint_id: 1, 
     application_id: 2, 
     environment_id: 3 
     }, 
     format: :json 
    } 
    } 

context "when processing a Post request with a mix of permitted and unpermitted parameters" do 
    before { post :create, mixed_params } 

    it "a create will not set the value of the unpermitted parameter" do 
    expect(JSON.parse(response.body)["id"]).not_to eq(1000) 
    end 

    it "a create will set the value of the permitted parameters" do 
    expect(JSON.parse(response.body)["blueprint_id"]).to eq(1) 
    expect(JSON.parse(response.body)["application_id"]).to eq(2) 
    expect(JSON.parse(response.body)["environment_id"]).to eq(3) 
    end 
end 

控制器代碼:

def create 
    @blueprint_application_environment = BlueprintApplicationEnvironment.new(blueprint_application_environment_params) 
    if @blueprint_application_environment.save 
     render 'show.json.jbuilder' 
    else 
     render json: @blueprint_application_environment.errors, status: :unprocessable_entity 
    end 
    end 

def blueprint_application_environment_params 
    params.require(:blueprint_application_environment).permit(:blueprint_id, :application_id, :environment_id) 
end 
7

我個人使用shoulda-matcher從thoughtbot。

的東西,如:

it do 
    should permit(:first_name, :last_name, :email, :password). 
    for(:update, params: params) 
end 
1

像您創建或使用強大的參數更新的對象,它也只是正常的你去做這件事的相似:

後:創建, book_id:@ book.id

但在強大的參數,你必須這樣做:

後:創建,{book_id:@ book.id,評論:{USER_ID:101,book_id: @ book.id,介紹道: 「值得購買」}}

你有傳入嵌套參數。