如何连接 RSpec 3.12 请求中的属性?

问题描述 投票:0回答:2

我的应用程序中的编辑视图提供了预期的数据字段,以及不属于模型的额外字段,例如注释和翻译,这些字段在保存编辑的记录之前由控制器方法处理。

在编写请求测试时,除了模型字段之外,我还需要向 Post 方法提供这些额外字段:

RSpec.describe "Playgrounds", type: :request do
  include Warden::Test::Helpers 
  # Playground. As you add validations to Playground, be sure to
  # adjust the attributes here as well.

  let(:user) { create(:user, is_admin: true) }
  let(:playground) {FactoryBot.create(:playground)}

  # User login 
  before do
    login_as user, scope: :user
  end

  describe "POST /playgrounds" do
    context "with valid attributes" do
      # Use per context let instead 
      let(:attributes) { attributes_for(:playground) }
      it "creates a playground" do
        expect {
          post '/entities', params: {
            playground: attributes, 
            playground_name_fr: "Donnée de test", 
            playground_name_de: "", 
            playground_name_en: "Test data", 
            playground_name_it: "Dati del test", 
            playground_description_fr: "Ceci n'est qu'un test", 
            playground_description_de: "", 
            playground_description_en: "This is just a test", 
            playground_description_it: "Questo è solo un test"
          }
        }.to change(Playground, :count).by(1)
        expect(response).to have_http_status 302
      end
    end 
  end
end

为了只定义一次用于翻译的这8个字段,我想定义一个Hash变量,并将其添加到playground Hash中:

RSpec.describe "Playgrounds", type: :request do
  include Warden::Test::Helpers 
  # Playground. As you add validations to Playground, be sure to
  # adjust the attributes here as well.

  let(:user) { create(:user, is_admin: true) }
  let(:playground) {FactoryBot.create(:playground)}
  let(:fields) do 
    { 
      playground_name_fr: "Donnée de test", 
      playground_name_de: "", 
      playground_name_en: "Test data", 
      playground_name_it: "Dati del test", 
      playground_description_fr: "Ceci n'est qu'un test", 
      playground_description_de: "", 
      playground_description_en: "This is just a test", 
      playground_description_it: "Questo è solo un test" 
    }
  end

    # User login 
    before do
        login_as user, scope: :user
    end

  describe "POST /playgrounds" do
    context "with valid attributes" do
      # Use per context let instead 
      let(:attributes) { attributes_for(:playground) }
      it "creates a playground" do
        expect {
          post '/entities', params: {
            playground: attributes < fields 
          }
        }.to change(Playground, :count).by(1)
        expect(response).to have_http_status 302
      end
    end 
  end
end 

但是我收到以下错误:

 Failure/Error:
   params.require(:playground)
         .permit(:code,
                 :status_id,
                 :logo,
                 :organisation_id,
                 :responsible_id,
                 :deputy_id,
                 :sort_code,
                 name: {},
                 description: {}

 NoMethodError:
   undefined method `permit' for "false":String

由于第一个语法按预期工作,而第二个语法则不然,我可能在磨损的位置或级别插入了字段,但我不知道如何解决这个问题?

谢谢您的帮助!

ruby-on-rails ruby rspec
2个回答
2
投票

要将哈希合并在一起,您可以使用

Hash#merge
:

expect {
  post '/entities', params: {
    playground: attributes.merge(fields)
  }
}.to change(Playground, :count).by(1)

Ruby 没有这方面的运算符简写。

Hash#<
实际上用于测试一个哈希值是否是另一个哈希值的子集并返回一个布尔值。


0
投票

问题是重现被测控制器期望的 params 哈希值。除了一些标记之外,params 还包含:

  • 游乐场哈希 - 对应于控制器中列出的允许参数
  • 其他参数 - 对应于编辑表单的额外字段

示例:

<ActionController::Parameters {"utf8"=>"✓", 
"authenticity_token"=>"uJysIqrglzyBSAx9O49TRZ4NfggMw9C59/w==",
"playground"=><ActionController::Parameters {
    "code"=>"TESTB", 
    "sort_code"=>"", 
    "organisation_id"=>"0", 
    "responsible_id"=>"1",  
    "deputy_id"=>"2"} permitted: false>, 
"playground_name_fr"=>"Société test", 
"playground_name_de"=>"Data governance", 
"playground_name_en"=>"TESTBC", 
"playground_name_it"=>"Società di test", 
"playground_description_fr"=>"", 
"playground_description_de"=>"", 
"playground_description_en"=>"", 
"playground_description_it"=>"", 
"controller"=>"playgrounds", 
"action"=>"create"} permitted: false>

那么解决方案是将 fields 哈希添加到 params 哈希本身:

    expect {
      post '/entities', params: {
        playground: attributes
      }.merge(fields)
    }.to change(Playground, :count).by(1)

非常感谢 Max 和 Eugen 让我上路!

© www.soinside.com 2019 - 2024. All rights reserved.