Posted over 6 years ago. Visible to the public. Repeats.

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

RSpec provides a nice diff when certain matchers fail.

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:, h:}.should match(t:, h: instance_of(Hash)) Failure/Error: {t:, h:}.should match(, 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.

makandra has been working exclusively with Ruby on Rails since 2007. Our laser focus on a single technology has made us a leader in this space.

Owner of this card:

Dominik Schöler
Last edit:
over 4 years ago
by Thomas Eisenbarth
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Dominik Schöler to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more