2014-06-18 52 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,介绍道: “值得购买”}}

你有传入嵌套参数。