Reputation: 433
When I send an object json all fields inside are changed to string, breaking my validation in the controller and i get the following error.
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)>
My test I try indicate 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
My factory is
FactoryGirl.define do
factory :bill do
description { FFaker::Lorem.phrase }
value { (rand() * 100).to_f }
end
end
My controller validations are
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
I try to change validation :value from Float
to :number
but the problem continues
I am using rails 4.2.3
and rspec 3.3.0
Upvotes: 8
Views: 7769
Reputation: 1380
In my case using rails 4.2, rspec 3.5 and ruby 2.3
post '/api/webhooks/v1/subscriptions', { abc: 134 }.to_json, headers
the to_json
part is the most important here and the headers have:
let(:headers) do
{
'Authorization' => 'Basic my-token',
'Content-Type' => 'application/json'
}
end
Upvotes: 0
Reputation: 23
None of above works for me.(rails 5.1.7, rspec 3.6)
The simple way you can give it a try is stub ActionController::Parameters
In my case, in controller I always use permit for strong 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
and then in Rspec I stub ActionController::Parameters like below
allow_any_instance_of(ActionController::Parameters).to receive(:permit).and_return(ActionController::Parameters.new(name: 'product name', price: 3000).permit(:name, :price)
just like that, and Rspec test checking Integer will work
NOTE: This can also apply with send boolean, float in params too.
Upvotes: 1
Reputation: 7684
For Rails 4 We can try this
post 'orders.json', JSON.dump(order: {boolean: true, integer: 123}), "CONTENT_TYPE" => "application/json"
Upvotes: 0
Reputation: 447
post :create, params: {}, as: :json
This is what works in Rails 5.0.3 and rspec-rails 3.6.0
Rails controller specs now inherit from ActionDispatch::IntegrationTest instead of ActionController::TestCase. But RSpec controller specs still use ActionController::TestCase which is deprecated. Relevant Rails commit here
Upvotes: 23
Reputation: 433
I added format json to post request and It worked like charm
before(:each) do
post :create, { bill: bill_attributes, format: :json }
end
Upvotes: 3