austinthesing
austinthesing

Reputation: 725

Rspec `eq` vs `eql` in `expect` tests

What is the difference between using eq and eql in rspec tests? Is there a difference between:

it "adds the correct information to entries" do
  # book = AddressBook.new # => Replaced by line 4
  book.add_entry('Ada Lovelace', '010.012.1815', '[email protected]')
  new_entry = book.entries[0]

  expect(new_entry.name).to eq('Ada Lovelace')
  expect(new_entry.phone_number).to eq('010.012.1815')
  expect(new_entry.email).to eq('[email protected]')
end

and:

it "adds the correct information to entries" do
  # book = AddressBook.new # => Replaced by line 4
  book.add_entry('Ada Lovelace', '010.012.1815', '[email protected]')
  new_entry = book.entries[0]

  expect(new_entry.name).to eql('Ada Lovelace')
  expect(new_entry.phone_number).to eql('010.012.1815')
  expect(new_entry.email).to eql('[email protected]')
end

Upvotes: 51

Views: 36702

Answers (2)

Faruk Hossain
Faruk Hossain

Reputation: 597

The differences are subtle.eq is the same as the ruby implementation of ==. On the other hand eql is the same as the ruby implementation of eql?.

eq checks object equivalence and will type cast to convert different object to the same type.

Two objects are equivalent if they are of the same class and have the same value but they are not necessarily the same object in memory.

expect(:my_symbol).to eq(:my_symbol)
# passes, both are identical.
expect('my string').to eq('my string')
# passes, objects are equivalent 
expect(5).to eq(5.0)
# passes, Objects are not equivalent but was type cast to same object type. 

eql checks object equivalence and does not try type casting.

expect(:my_symbol).to eql(:my_symbol)
# passes, both are identical.
expect('my string').to eql('my string')
# passes, objects are equivalent but not identical 
expect(5).to eql(5.0)
# fails, Objects are not equivalence, did not try to type cast

equal checks object identity. Two object are identical if they are the same object meaning they have same object id (share the same address in memory).

expect(:my_symbol).to equal(:my_symbol)
# passes, both are identical.
expect('my string').to equal('my string')
# fails, objects are equivalent but not identical
expect(5).to equal(5.0)
# fails, objects are not equivalent and not identical

Upvotes: 40

stef
stef

Reputation: 14268

There are subtle differences here, based on the type of equality being used in the comparison.

From the Rpsec docs:

Ruby exposes several different methods for handling equality:

a.equal?(b) # object identity - a and b refer to the same object
a.eql?(b) # object equivalence - a and b have the same value
a == b # object equivalence - a and b have the same value with type conversions]

eq uses the == operator for comparison, and eql ignores type conversions.

Upvotes: 60

Related Questions