In RSpec, when you first start writing test cases to compare expected results, it might be very confusing to pick from "be", "eq", "eql" or "equal".

However, once you know the underlying differences of these methods, everything will be clear afterward. Let me go through them here with some examples.

Compare Statements

There are 2 groups of compare methods.

The followings compare the value of the object:

  • eq
  • eql

These two compare the object_id of the object instead:

  • equal
  • be

Test Case Example

In the following test case, I am going to use String, Array and Fixnum data to demonstrate the differences of "eq", "eql", "equal", "be".

Fixnum

``` require 'rails_helper'

describe 'Fixnum' do
it('should find two Fixnums are equal') { 1.should eq 1 }
it('should find two Fixnums are equal') { 1.should eql 1 }
it('should find two Fixnums are equal') { 1.should equal 1 }
it('should find two Fixnums are equal') { 1.should be 1 }
end

In case of _Fixnum_, it will all process successful. It is because _Fixnum_ with the same value are actually the same single data instance, i.e. 1 and 1 are referring the same instance in the memory.

####_String_
<font size='3'>

describe 'String' do
it('should find two strings are equal') { "".should eq ""}
it('should find two strings are equal') { "".should eql ""}
it('should find two Strings are equal') { "".should equal ""} # Failed
it('should find two strings are equal') { "".should be ""} # Failed
end

In case of _String_, it will fail on "<font face="Courier New">equal</font>" and "<font face="Courier New">be</font>" statements. It is because these _String_ data are different instances. First two test cases are comparing their values, which are the same. However, third and fourth test cases are comparing if they are the same object instance, which is not.

####_Array_
<font size='3'>

describe 'Array' do
it('should find two Arrays are equal') { {:a => 1}.should eq :a => 1 }
it('should find two Arrays are equal') { {:a => 1}.should eql :a => 1 }
it('should find two Arrays are equal') { {:a => 1}.should equal :a => 1 } # Failed
it('hould find two Arrays are equal') { {:a => 1}.should be :a => 1 } # Failed
end

In case of _Array_, it will fail on "<font face="Courier New">equal</font>" and "<font face="Courier New">be</font>" statements. The reason are the same as _String_ cases.


### Conclusion

We can see that "<font face="Courier New">eq</font>" and "<font face="Courier New">eql</font>" are used to compare the __object value__,
while "<font face="Courier New">equal</font>" and "<font face="Courier New">be</font>" are used to compare the __object_id__ by referencing the above result.


That's mean the compare statements of checking the __object_id__ are using for compare the *Fixnum* data.

The compare statements of checking the __object value__ are using for compare the normal data type, e.g. *String*, *Array* ... 


<hr>

### Reference

Suzuki MilanPaak. 17 JUN 2012. RSpecのequal, eql, eq, be の違い. Retrieved from :
<font size='2'>http://engineerflies.blogspot.hk/2012/06/rspecequal-eql-eq-be.html#.WWght9OGOi5</font>

myronmarston. Last published at May 2017. Equality matchers. Retrieved from : 
<font size='2'>https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/equality-matchers</font>