我的应用程序中的编辑视图提供了预期的数据字段,以及不属于模型的额外字段,例如注释和翻译,这些字段在保存编辑的记录之前由控制器方法处理。
在编写请求测试时,除了模型字段之外,我还需要向 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
由于第一个语法按预期工作,而第二个语法则不然,我可能在磨损的位置或级别插入了字段,但我不知道如何解决这个问题?
谢谢您的帮助!
Hash#merge
:
expect {
post '/entities', params: {
playground: attributes.merge(fields)
}
}.to change(Playground, :count).by(1)
Hash#<
实际上用于测试一个哈希值是否是另一个哈希值的子集并返回一个布尔值。
问题是重现被测控制器期望的 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 让我上路!