Guitars

Adventures in Ruby - Setting up your tests in RSpec with Let

Nov 21, 2019

I had been using Minitests for unit testing for a while but decided for a small project to see if I could level up my unit testing skills. RSpec provides some really nice syntax which helps to write tests with really clear purposes:

RSpec.describe Thing do
  describe '#instance_method' do
    it 'does a thing that produces a value' do
      new_thing = Thing.new()
      expect(new_thing.instance_method).to eql(some_value)
    end
  end
end

Even though the above pseudo-ruby is pretty abstract, you can see that we’re creating an instance of a class and testing that some method on that instance returns a particular value.

The instance of this class is only available within the scope of the test we are creating here, but what if we want to test dozens of instance methods? Creating a class instance in every test would get pretty repetitive pretty quickly.

What really got me fired up about RSpec was the ease with which you can create sample class instances at the top of your unit tests that you can use throughout. Let’s get more specific and create a shopping basket (I love guitars so let’s put a guitar and an amplifier in that basket)

RSpec.describe ShoppingBasket do
  let(:new_basket) do
    new_basket = ShoppingBasket.new
    new_basket.add(item: 'Telecaster', price: 1300.00)
    new_basket.add(item: 'Marshall JVM', price: 1000.00)
    new_basket
  end
  
  describe '#instance_method' do
    expect(new_basket.instance_method) to eql(some_value)
  end

end

So now I’ve created a sample class instance that I can then run through all of my tests by using the let helper method. This is new-ing up my shopping basket as a new_basket variable that can be passed into all of my unit tests.