everydayrails/rails-4-1-rspec-3-0

Ch 9 spec fails

arturtr opened this issue · 6 comments

spec/controllers/contacts_controller_spec.rb:199 fails with

Failures:

  1) ContactsController administrator access behaves like full access to contacts PATCH #update invalid attributes does not change the contact's attributes
     Failure/Error: expect(assigns(:contact).reload.attributes).to eq contact.attributes

       expected: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"evert.gottlieb@carter.com", "created_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "hidden"=>false}
            got: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"evert.gottlieb@carter.com", "created_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "hidden"=>false}

       (compared using ==)

       Diff:

     Shared Example Group: "full access to contacts" called from ./spec/controllers/contacts_controller_spec.rb:233
     # ./spec/controllers/contacts_controller_spec.rb:199:in `block (5 levels) in <top (required)>'
     # ./spec/rails_helper.rb:38:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:37:in `block (2 levels) in <top (required)>'

  2) ContactsController user access behaves like full access to contacts PATCH #update invalid attributes does not change the contact's attributes
     Failure/Error: expect(assigns(:contact).reload.attributes).to eq contact.attributes

       expected: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"danika@wilderman.com", "created_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "hidden"=>false}
            got: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"danika@wilderman.com", "created_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "hidden"=>false}

       (compared using ==)

       Diff:

     Shared Example Group: "full access to contacts" called from ./spec/controllers/contacts_controller_spec.rb:242
     # ./spec/controllers/contacts_controller_spec.rb:199:in `block (5 levels) in <top (required)>'
     # ./spec/rails_helper.rb:38:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:37:in `block (2 levels) in <top (required)>'

in branch https://github.com/everydayrails/rails-4-1-rspec-3-0/tree/09_speedup

I’m not able to reproduce this. Could you send me any more details (Ruby version, OS …)? Thanks.

On Jan 8, 2015, at 12:22 AM, Artur Trofimov notifications@github.com wrote:

spec/controllers/contacts_controller_spec.rb:199 fails with

Failures:

  1. ContactsController administrator access behaves like full access to contacts PATCH #update invalid attributes does not change the contact's attributes
    Failure/Error: expect(assigns(:contact).reload.attributes).to eq contact.attributes
   expected: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"evert.gottlieb@carter.com", "created_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "hidden"=>false}
        got: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"evert.gottlieb@carter.com", "created_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:40 UTC +00:00, "hidden"=>false}

   (compared using ==)

   Diff:

 Shared Example Group: "full access to contacts" called from ./spec/controllers/contacts_controller_spec.rb:233
 # ./spec/controllers/contacts_controller_spec.rb:199:in `block (5 levels) in <top (required)>'
 # ./spec/rails_helper.rb:38:in `block (3 levels) in <top (required)>'
 # ./spec/rails_helper.rb:37:in `block (2 levels) in <top (required)>'
  1. ContactsController user access behaves like full access to contacts PATCH #update invalid attributes does not change the contact's attributes
    Failure/Error: expect(assigns(:contact).reload.attributes).to eq contact.attributes
   expected: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"danika@wilderman.com", "created_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "hidden"=>false}
        got: {"id"=>2, "firstname"=>"Lawrence", "lastname"=>"Smith", "email"=>"danika@wilderman.com", "created_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "updated_at"=>Thu, 08 Jan 2015 06:18:41 UTC +00:00, "hidden"=>false}

   (compared using ==)

   Diff:

 Shared Example Group: "full access to contacts" called from ./spec/controllers/contacts_controller_spec.rb:242
 # ./spec/controllers/contacts_controller_spec.rb:199:in `block (5 levels) in <top (required)>'
 # ./spec/rails_helper.rb:38:in `block (3 levels) in <top (required)>'
 # ./spec/rails_helper.rb:37:in `block (2 levels) in <top (required)>'

in branch https://github.com/everydayrails/rails-4-1-rspec-3-0/tree/09_speedup https://github.com/everydayrails/rails-4-1-rspec-3-0/tree/09_speedup

Reply to this email directly or view it on GitHub #48.

rbenv 0.4.0-129-g7e0e85b
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]

Distributor ID: Ubuntu
Description:    Ubuntu 14.10
Release:    14.10
Codename:   utopic

This is likely due to your database. Many databases do not have the same precision for timestamps. So it's likely that the created_at and updated_at timestamps have microsecond precision in the object, but when retrieved from the database it does not.

@cupakromer yes this is the reason: Ruby Time object maintains greater precision than the database does.

For solve the problem in spec I reloaded both of variables.

        it "does not change the contact's attributes" do
          expect(assigns(:contact).reload.attributes).to eq contact.reload.attributes
        end

But maybe greatest solution is here
http://stackoverflow.com/a/20403290/759812

Timecop not helps here because the different precision in ruby time object and sqlite time

I would consider using the the monkey patch from ActiveSupport: Hash#except. I would probably re-write the spec:

it "does not change the contact's attributes" do
  ignored_attributes = [:created_at, :updated_at]
  database_attributes = assigns(:contact).reload.attributes.except(ignored_attributes)
  original_attributes = contact.attributes.except(ignored_attributes)
  expect(database_attributes).to eq original_attributes
end

In case someone finds this issue in a Google search (like I did), the following example also works as the block passed to change always loads the data from the DB (even for the first time), so there is no difference in the time decimal precision.

it "does not update the requested person" do
  expect {
    patch :update, id: person, person: invalid_attributes
  }.not_to change { Person.find(person.id).attributes }
end

A similar issue is also discussed here.