【问题标题】:How to test strong params with Rspec?如何使用 Rspec 测试强参数?
【发布时间】:2014-06-18 17:58:15
【问题描述】:

使用 Rspec 在 Rails 控制器中测试强参数过滤的实际策略是什么? (除了应该匹配器)如何编写失败的测试然后使其变为绿色?

【问题讨论】:

  • 我的回答有帮助吗?也许我可以澄清一些事情。
  • 谢谢你,你真的帮了我。我不知道with_indifferent_access。以及如何测试属性要求,例如 params.require :user?

标签: ruby-on-rails ruby ruby-on-rails-4 rspec rspec-rails


【解决方案1】:

使用预期和所有(不满足)参数创建 2 个哈希。然后将所有参数传递给操作并检查您的对象模型是否仅接收预期的参数。如果您不使用强参数过滤器,则不会。比为参数添加权限并再次检查测试。

例如,这个:

# 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

会将所有参数传递给用户并且测试将失败。当你过滤它们时:

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

并用User.create(user_params) 更改操作,测试将通过。

【讨论】:

  • create 是在ActiveRecord::Base 上定义并由User 继承的类级方法。因此,虽然expect_any_instance(User)User 实例的模拟期望)可能有效,但expect(User)User 类的模拟期望)也可以工作,而且更小。跨度>
【解决方案2】:

我个人使用来自thoughtbot 的shoulda-matcher

类似的东西:

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

【讨论】:

    【解决方案3】:

    我是这样做的:

      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
    

    【讨论】:

      【解决方案4】:

      就像您使用强参数创建或更新对象一样,它也相似,除了您通常会这样做的一件事:

      post :create, book_id: @book.id

      但在强参数中你必须这样做:

      post :create, {book_id: @book.id, comment: {user_id: 101, book_id: @book.id,描述:“值得购买”}}

      你必须传入嵌套参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多