Ruby on Rails testing

RSpec – why is important to specify how many times given function is executed

RSpec – why is important to specify how many times given function is executed February 24, 2018Leave a comment

RSpec allows you to expect how many times given method would be called. Before I will present how we can do this, is important to know why we want to do this. It’s all about having control over the behavior of our code. To better demonstrate it, let’s write invalid code:

class SomeClass
  def something
    @something = service.call
  end
end

Why this code is invalid? We want to use memoization here to not call service.call more than once each time SomeClass#something is called. However, instead of ||= we used = operator and our code does not work as expected.

If in our code we would write something like this:

expect(some_class_instance).to have_received(:something)

We would not catch our mistake. Our example is really simple but imagine that service.call calls external API and consumes limited resources – then it’s really bad. How we can avoid it? By specifying how many times our method should be called:

expect(some_class_instance).to have_received(:something).once

And with such expectation, we would catch our mistake. If we would use Test Driven Development approach it would never be created. This case shows how is important to use TDD and write detailed expectations.

RSpec syntax for expecting message to be called more than once

What if we want to test if our code was called more than once or at least 2 or 3 times? RSpec allows us to specify this also.

Expect message to be called n times:

expect(some_class_instance).to have_received(:something).once
expect(some_class_instance).to have_received(:something).twice
expect(some_class_instance).to have_received(:something).exactly(3).times

Expect message to be called at least n times:

expect(some_class_instance).to have_received(:something).at_least(:once)
expect(some_class_instance).to have_received(:something).at_least(:twice)
expect(some_class_instance).to have_received(:something).at_last(3).times

Expect message to be called at most n times:

expect(some_class_instance).to have_received(:something).at_most(:once)
expect(some_class_instance).to have_received(:something).at_most(:twice)
expect(some_class_instance).to have_received(:something).at_most(3).times

Download free RSpec & TDD ebook

Do you want to earn more or jump to the next level in your company? Do you know that testing skills are one of the most desired skills? There is only first step: start testing and do it right. My ebook can help you. Subscribe to the newsletter to get a free copy of the book.

Leave a Reply

Your email address will not be published. Required fields are marked *