What is RSpec ?

RSpec is a testing tool written to test Ruby code. It can be used to test Ruby program as well as parts of a Ruby on Rails application. It is a behavior-driven development (BDD) framework which is extensively used in the production applications. The beauty of RSpec is that it is written in a shared language, which improves communication between tech and non-tech teams and stakeholders. The simplicity in the RSpec syntax makes it one of the popular testing tools for Ruby applications.

RSpec Syntax

Lets first look at a basic syntax of a sample testcase.

  describe 'sample testcase' do
    it 'checks if true is equal to true' do
      x = true
      expect(x).to eq(true)
    end
  end

Equivalence Matchers

Today I will talk about the most commonly used RSpec Matcher known as Equivalence Matcher. My focus will be to highlight the significance of each of the provided Equivalence matchers by RSpec. So lets look into the its variants.

Loose Equality (eq)

Loose equality matcher eq can be called on two objects where almost equality is needed.

  a = "3 balls"
  b = "3 balls"
  expect(a).to eq(b) #Passes the test

However, there can be a case when we are given a result of decimal (with zero in decimal places) which is being compared with an integer. It will also pass with loose equality. Lets look at an example:

  number = 17
  decimal = 17.00
  # 17 and 17.00 is different but "close enough"
  expect(number).to eq(decimal)      #Passes the test

  #Another way of checking loose equality
  expect(number).to be == decimal    #Passes the test

So eq is checking the objects loosely, not concerned with their specific types i.e. integer and decimal comparison can be passed through the testcase.

Value Equality (eql)

Now, while writing a program there will be situations where you want to make sure decimal is not equal to an integer i.e. you want the values to match exactly.

    number = 17
    decimal = 17.00
    # 17 and 17.00 are different but "close enough"
    expect(number).to eql(decimal)      #Fails the test

Now lets see what happens if we say 17 and 17.00 are not value equal. Lets replace eq by not_to eql.

    number = 17
    decimal = 17.00
    # 17 and 17.00 not the same, close doesn't count 
    expect(number).not_to eql(decimal) #Passes the test

Identity Equality (equal)

Sometimes you want that the object should be same. This means that the two objects compared should be exactly same (having same memory allocation). Behind the scenes of equal, Ruby checks if the object_id of both objects are same.

    it 'will match identity equality with #equal' do
      a = "2 cats"
      b = "2 cats"
      expect(a).not_to equal(b) # same value, but different object

      c = b                     #c.object_id is same as b.object_id
      expect(b).to equal(c)     # same object
      expect(b).to be(c)        # synonym for #equal
    end
    

To sum up the discussion, you should use