This is the default test generated with a scaffold I created.
describe "PUT update", focus: true do
describe "with valid params" do
it "updates the requested purchase_order" do
current_valid_attr = valid_attributes
purchase_order = PurchaseOrder.create! current_valid_attr
# Assuming there are no other purchase_orders in the database, this
# specifies that the PurchaseOrder created on the previous line
# receives the :update_attributes message with whatever params are
# submitted in the request.
# PurchaseOrder.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
# put :update, :id => purchase_order.id, :purchase_order => {'these' => 'params'}
PurchaseOrder.any_instance.should_receive(:update_attributes).with(current_valid_attr)
put :update, :id => purchase_order.id, :purchase_order => current_valid_attr
end
The problem is I don’t understand what it is supposed to do and I can’t make it pass with the correct attributes. Here’s the error when I ran the test
Failures:
1) PurchaseOrdersController PUT update with valid params updates the requested purchase_order
Failure/Error: put :update, :id => purchase_order.id, :purchase_order => current_valid_attr
#<PurchaseOrder:0x007fe3027521e0> received :update_attributes with unexpected arguments
expected: ({"id"=>nil, "supplier_id"=>1, "no"=>1305, "no_rujukan"=>"Guiseppe Abshire", "jenis"=>"P", "mula_on"=>Sat, 23 Aug 2003 14:11:42 MYT +08:00, "created_at"=>nil, "updated_at"=>nil})
got: ({"id"=>nil, "supplier_id"=>"1", "no"=>"1305", "no_rujukan"=>"Guiseppe Abshire", "jenis"=>"P", "mula_on"=>"2003-08-23 14:11:42 +0800", "created_at"=>nil, "updated_at"=>nil})
Thanks in advance.
valid_attributes
def valid_attributes
Factory.build(:purchase_order).attributes
end
The factory
FactoryGirl.define do
factory :purchase_order do
association :supplier
sequence(:no) { |n| Random.rand(1000...9999) }
sequence(:no_rujukan) { |n| Faker::Name.name }
sequence(:jenis) { |n| PurchaseOrder::PEROLEHAN[Random.rand(0..3).to_i] }
sequence(:mula_on) { |n| Random.rand(10.year).ago }
end
end
This test checks that when request comes to
PurchaseOrdersController#updateactionupdate_attributesmethod for one ofPurchaseOrdermodels is called and request parameters are properly passed to this method.The problem here (as stated by error message) is that
update_attributesis called with hash of attributes that has all values of typeString. That’s because all values ofparamshash (containing all request parameters) that is most likely used inupdateaction are strings.On the other hand your
current_valid_attrhash contains values of different types likeFixnumandTime. And when time comes to compare expected and received values you get an error, because, for example,noattribute was expected to be Fixnum1305, but after submitting request it was converted to string andupdate_attributesreceived String'1305'instead.One of the ways to fix the problem is to ensure that all values in
current_valid_attrare strings:Updated
There is
paramify_valuesmethod that can be used in tests to convert hash of parameters to the same form that will be received by controller inparamshash.