请求规范中的 Rails API post 应传递参数但变空
Rails API post in request spec should pass params but getting empty
首先,在我的请求规范中 sites.spec.rb
我有这个测试:
describe "POST /v1/sites" do
let(:valid_attributes) { { url: "www.example.com", site_code: "123456" } }
context 'when the request is valid' do
before { post v1_sites_path, params: valid_attributes }
it 'creates a site' do
expect(json['url']).to eq("www.example.com")
expect(json['site_code']).to eq("123456")
end
it 'returns status code 201' do
expect(response).to have_http_status(201)
end
end
然后我得到了 "creates a site"...
的失败测试
1) Sites POST /v1/sites when the request is valid creates a site
Failure/Error: expect(json['url']).to eq("www.example.com")
expected: "www.example.com"
got: ["can't be blank"]
(compared using ==)
# ./spec/requests/sites_spec.rb:61:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:84:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:83:in `block (2 levels) in <top (required)>'
现在这在技术上是有道理的,因为我的网站模型已经验证:url,:site_code,存在:真。所以测试失败了,因为 post 没有正确传递参数。
最后,这里是控制器:
module Api::V1
class SitesController < BaseApiController
before_action :set_site, only: [:show, :update, :destroy]
# GET /sites
def index
@sites = Site.all
render json: @sites
end
# GET /sites/1
def show
render json: @site
end
# POST /sites
def create
@site = Site.new(site_params)
if @site.save
render json: @site, status: :created, location: @site
else
render json: @site.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /sites/1
def update
if @site.update(site_params)
render json: @site
else
render json: @site.errors, status: :unprocessable_entity
end
end
# DELETE /sites/1
def destroy
@site.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site
@site = Site.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def site_params
# params.require(:data).require(:attributes).permit(:url, :side_code, :user_id)
# params.require(:site).permit(:url, :side_code, :user_id)
params.fetch(:site, {}).permit(:url, :side_code)
end
end
end
我推测我将 Rails API 的参数传递给 post 的方式可能格式不正确或不正确,或者完全是其他原因。我确实在测试块中玩过 params
尝试数据:{ attributes: valid_attributes } 没有运气。
非常感谢任何想法或建议!
这个问题确实是由于我在测试块中传递给 POST 请求的参数格式所致。我通过命令行测试了 POST 并观察了 rails 服务器以查看参数是如何通过的。他们看起来像这样:
Parameters: {"site_code"=>"123456", "url"=>"www.updated.com", "subdomain"=>"api", "id"=>"2", "site"=>{"site_code"=>"123456", "url"=>"www.updated.com"}}
然后在我的 sites_spec.rb 中,我为 post 请求的有效参数复制了这种格式:
let(:valid_attributes) { { "site"=>{"url"=>"www.example.com", "user_id"=>user_id, "site_code"=>"123456"} } }
这行得通。参数的 JSON 格式需要在测试块中按照与真实 JSON 请求相同的方式进行格式化。
首先,在我的请求规范中 sites.spec.rb
我有这个测试:
describe "POST /v1/sites" do
let(:valid_attributes) { { url: "www.example.com", site_code: "123456" } }
context 'when the request is valid' do
before { post v1_sites_path, params: valid_attributes }
it 'creates a site' do
expect(json['url']).to eq("www.example.com")
expect(json['site_code']).to eq("123456")
end
it 'returns status code 201' do
expect(response).to have_http_status(201)
end
end
然后我得到了 "creates a site"...
的失败测试1) Sites POST /v1/sites when the request is valid creates a site
Failure/Error: expect(json['url']).to eq("www.example.com")
expected: "www.example.com"
got: ["can't be blank"]
(compared using ==)
# ./spec/requests/sites_spec.rb:61:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:84:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:83:in `block (2 levels) in <top (required)>'
现在这在技术上是有道理的,因为我的网站模型已经验证:url,:site_code,存在:真。所以测试失败了,因为 post 没有正确传递参数。
最后,这里是控制器:
module Api::V1
class SitesController < BaseApiController
before_action :set_site, only: [:show, :update, :destroy]
# GET /sites
def index
@sites = Site.all
render json: @sites
end
# GET /sites/1
def show
render json: @site
end
# POST /sites
def create
@site = Site.new(site_params)
if @site.save
render json: @site, status: :created, location: @site
else
render json: @site.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /sites/1
def update
if @site.update(site_params)
render json: @site
else
render json: @site.errors, status: :unprocessable_entity
end
end
# DELETE /sites/1
def destroy
@site.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site
@site = Site.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def site_params
# params.require(:data).require(:attributes).permit(:url, :side_code, :user_id)
# params.require(:site).permit(:url, :side_code, :user_id)
params.fetch(:site, {}).permit(:url, :side_code)
end
end
end
我推测我将 Rails API 的参数传递给 post 的方式可能格式不正确或不正确,或者完全是其他原因。我确实在测试块中玩过 params
尝试数据:{ attributes: valid_attributes } 没有运气。
非常感谢任何想法或建议!
这个问题确实是由于我在测试块中传递给 POST 请求的参数格式所致。我通过命令行测试了 POST 并观察了 rails 服务器以查看参数是如何通过的。他们看起来像这样:
Parameters: {"site_code"=>"123456", "url"=>"www.updated.com", "subdomain"=>"api", "id"=>"2", "site"=>{"site_code"=>"123456", "url"=>"www.updated.com"}}
然后在我的 sites_spec.rb 中,我为 post 请求的有效参数复制了这种格式:
let(:valid_attributes) { { "site"=>{"url"=>"www.example.com", "user_id"=>user_id, "site_code"=>"123456"} } }
这行得通。参数的 JSON 格式需要在测试块中按照与真实 JSON 请求相同的方式进行格式化。