Read more

Heads up: RSpec's diffs may not tell the truth

Dominik Schöler
March 16, 2016Software engineer at makandra GmbH

RSpec provides a nice diff when certain matchers fail.

Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

Here is an example where this diff is helpful while comparing two hashes:

{a:1}.should match(a:1, b:2)

Failure/Error: {a:1}.should match(a:1, b:2)
  expected {:a=>1} to match {:a=>1, :b=>2}
  Diff:
  @@ -1,3 +1,2 @@
   :a => 1,
  -:b => 2,

Unfortunately, this diff is not as clever as it would need to. RSpec's instance_of matchers will look like errors in the diff (even if they are not), and time objects that differ only in milliseconds won't appear in the diff (although they should):

# Because they are evaluated after each other, the two timestamps below differ marginally
{t: Time.now, h: Hash.new}.should match(t: Time.now, h: instance_of(Hash))
     
Failure/Error: {t: Time.now, h: Hash.new}.should match(t:Time.now, h: instance_of(Hash))
  expected {:t=>2016-03-16 08:02:16 +0100, :h=>{}} to match {:t=>2016-03-16 08:02:16 +0100, :h=>#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x0000000b87ce58 @klass=Hash>}
  Diff:
  @@ -1,3 +1,3 @@
  -:h => #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x0000000b87ce58 @klass=Hash>,
  +:h => {}, # <== Looks like an error, but is not: {} matches the matcher above
   :t => 2016-03-16 08:02:16 +0100, # <== Actual error: milliseconds differ

Note that while the {} vs instance_of(Hash) oddity shows up in the diff, it is not treated as an error. As soon as the millisecond offset is fixed (see this card for details), the spec will pass.

Keep this in mind and don't trust RSpec's diffs too much.

Posted by Dominik Schöler to makandra dev (2016-03-16 07:54)