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

How to concatenate attributes in RSpec 3.12 requests?

提问人:user1185081 提问时间:11/3/2023 最后编辑:Jason Alleruser1185081 更新时间:11/4/2023 访问量:32

问:

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

在编写请求测试时,除了模型字段外,我还需要向 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 红宝石 rspec

评论

0赞 eugen 11/3/2023
您可能想要而不是 .post '/entities', params: { playground: attributes.merge(fields) }attributes < fields
0赞 user1185081 11/4/2023
你是对的,我正在与数组混淆......这是一个很好的步骤,但不幸的是,还不是解决方案!

答:

2赞 max 11/3/2023 #1

要将哈希合并在一起,请使用 Hash#merge

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

Ruby 没有运算符的简写。Hash#< 实际上用于测试一个哈希是否是另一个哈希的子集并返回布尔值。

1赞 user1185081 11/4/2023 #2

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

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

例:

<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>

那么解决方案是将字段哈希添加到参数哈希本身:

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

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