提问人:user1185081 提问时间:11/3/2023 最后编辑:Jason Alleruser1185081 更新时间:11/4/2023 访问量:32
如何连接RSpec 3.12请求中的属性?
How to concatenate attributes in RSpec 3.12 requests?
问:
我的应用程序中的编辑视图提供了预期的数据字段,以及不属于模型的额外字段,例如注释和平移,这些字段在保存编辑的记录之前由控制器方法处理。
在编写请求测试时,除了模型字段外,我还需要向 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
由于第一种语法按预期工作,而第二种语法则没有,我可能在错误的位置或级别插入了字段,但我找不到解决这个问题的方法?
感谢您的帮助!
答:
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让我上路!
评论
post '/entities', params: { playground: attributes.merge(fields) }
attributes < fields