Rspec 将 Post 参数格式化为字符串值
Rspec format Post parameters to String values
当我发送对象时 json 里面的所有字段都更改为字符串,破坏了我在控制器中的验证并且我收到以下错误。
Api::V1::BillsController POST #create when logged in
Failure/Error: post :create, { bill: bill_attributes }
Apipie::ParamInvalid:
Invalid parameter 'value' value "41.64794235693306": Must be Float
# ./app/controllers/concerns/exception_aspects.rb:4:in exception_wrapper
# ./spec/controllers/api/v1/bills_controller_spec.rb:135:in block (4 levels) in <top (required)>
我的测试我试表明request.headers['Content-Type'] = 'application/json'
let(:bill_attributes) { FactoryGirl.attributes_for :bill }
before(:each) do
request.headers['Content-Type'] = 'application/json'
post :create, { bill: bill_attributes }
end
it "when is valid description" do
expect(json_response[:description]).to eq(bill_attributes[:description])
end
我的工厂是
FactoryGirl.define do
factory :bill do
description { FFaker::Lorem.phrase }
value { (rand() * 100).to_f }
end
end
我的控制器验证是
api :POST, "/bills", "Add a new bill to an event"
description "Add a new bill"
param :bill, Hash, :required => true, :action_aware => true do
param :description, String, "Bill description"
param :bill_photo, Hash, :required => false do
param :base64image, String, "Base 64 image file"
end
param :value, Float, "Amount of the bill"
end
我尝试将验证:值从 Float
更改为 :number
,但问题仍然存在
我正在使用 rails 4.2.3
和 rspec 3.3.0
我在 post 请求中添加了格式 json,效果很好
before(:each) do
post :create, { bill: bill_attributes, format: :json }
end
post :create, params: {}, as: :json
这在 Rails 5.0.3 和 rspec-rails 3.6.0
中有效
Rails 控制器规格现在继承自 ActionDispatch::IntegrationTest 而不是 ActionController::TestCase。但是 RSpec 控制器规范仍然使用 ActionController::TestCase,但已弃用。
Relevant Rails commit here
对于Rails 4 我们可以试试这个
post 'orders.json', JSON.dump(order: {boolean: true, integer: 123}), "CONTENT_TYPE" => "application/json"
以上的 None 对我有用。(rails 5.1.7,rspec 3.6)
您可以尝试的简单方法是存根 ActionController::Parameters
就我而言,在控制器中我总是对强参数使用许可。
def product_parameters
_params = params.permit :name, :price
# validate for price is integer
raise BadRequest, code: 'blah_code' unless _params[:price].is_a?(Integer)
end
然后在 Rspec 我存根 ActionController::Parameters 如下
allow_any_instance_of(ActionController::Parameters).to receive(:permit).and_return(ActionController::Parameters.new(name: 'product name', price: 3000).permit(:name, :price)
就这样,Rspec 测试检查 Integer 就可以了
NOTE: This can also apply with send boolean, float in params too.
在我的例子中使用 rails 4.2、rspec 3.5 和 ruby 2.3
post '/api/webhooks/v1/subscriptions', { abc: 134 }.to_json, headers
to_json
部分在这里是最重要的,headers 有:
let(:headers) do
{
'Authorization' => 'Basic my-token',
'Content-Type' => 'application/json'
}
end
当我发送对象时 json 里面的所有字段都更改为字符串,破坏了我在控制器中的验证并且我收到以下错误。
Api::V1::BillsController POST #create when logged in
Failure/Error: post :create, { bill: bill_attributes }
Apipie::ParamInvalid:
Invalid parameter 'value' value "41.64794235693306": Must be Float
# ./app/controllers/concerns/exception_aspects.rb:4:in exception_wrapper
# ./spec/controllers/api/v1/bills_controller_spec.rb:135:in block (4 levels) in <top (required)>
我的测试我试表明request.headers['Content-Type'] = 'application/json'
let(:bill_attributes) { FactoryGirl.attributes_for :bill }
before(:each) do
request.headers['Content-Type'] = 'application/json'
post :create, { bill: bill_attributes }
end
it "when is valid description" do
expect(json_response[:description]).to eq(bill_attributes[:description])
end
我的工厂是
FactoryGirl.define do
factory :bill do
description { FFaker::Lorem.phrase }
value { (rand() * 100).to_f }
end
end
我的控制器验证是
api :POST, "/bills", "Add a new bill to an event"
description "Add a new bill"
param :bill, Hash, :required => true, :action_aware => true do
param :description, String, "Bill description"
param :bill_photo, Hash, :required => false do
param :base64image, String, "Base 64 image file"
end
param :value, Float, "Amount of the bill"
end
我尝试将验证:值从 Float
更改为 :number
,但问题仍然存在
我正在使用 rails 4.2.3
和 rspec 3.3.0
我在 post 请求中添加了格式 json,效果很好
before(:each) do
post :create, { bill: bill_attributes, format: :json }
end
post :create, params: {}, as: :json
这在 Rails 5.0.3 和 rspec-rails 3.6.0
中有效Rails 控制器规格现在继承自 ActionDispatch::IntegrationTest 而不是 ActionController::TestCase。但是 RSpec 控制器规范仍然使用 ActionController::TestCase,但已弃用。 Relevant Rails commit here
对于Rails 4 我们可以试试这个
post 'orders.json', JSON.dump(order: {boolean: true, integer: 123}), "CONTENT_TYPE" => "application/json"
None 对我有用。(rails 5.1.7,rspec 3.6)
您可以尝试的简单方法是存根 ActionController::Parameters
就我而言,在控制器中我总是对强参数使用许可。
def product_parameters
_params = params.permit :name, :price
# validate for price is integer
raise BadRequest, code: 'blah_code' unless _params[:price].is_a?(Integer)
end
然后在 Rspec 我存根 ActionController::Parameters 如下
allow_any_instance_of(ActionController::Parameters).to receive(:permit).and_return(ActionController::Parameters.new(name: 'product name', price: 3000).permit(:name, :price)
就这样,Rspec 测试检查 Integer 就可以了
NOTE: This can also apply with send boolean, float in params too.
在我的例子中使用 rails 4.2、rspec 3.5 和 ruby 2.3
post '/api/webhooks/v1/subscriptions', { abc: 134 }.to_json, headers
to_json
部分在这里是最重要的,headers 有:
let(:headers) do
{
'Authorization' => 'Basic my-token',
'Content-Type' => 'application/json'
}
end