Last Updated: September 29, 2021
· vumanhcuongit

RSpec: allow vs expect

You know allow and expect are used in rspec-mocks, but you are confused with them ?. Don't worry, I'll explain them briefly.


book = double("book")
allow(book).to receive(:title) { "The RSpec Book" }

You ASSUME that book object has a method title and it'll return "The RSpec Book" when this method's called.


book = double("book")
allow(book).to receive(:title) { "The RSpec Book" }
expect(book).to receive(:title) { "The RSpec Book" }

This example's a bit different. You EXPECT that when book object calls title method, it'll return that string "The RSpec Book".

Sum up:

A big difference between them is that ASSUME and EXPECT

Deep magic:

why do we use 'allow' ?
To answer this question, we should refer to the concept of Test Doubles:

A test double is an object that stands in for another object in your system during a code example

This object isn't existed in your real system, it doesn't own methods and attributes. So we need to use allow to assume that this object has some methods and returns predefined values.

That's all, and thanks for your concern. If you have any questions, please don't hesitate to ask me :).

1 Response
Add your response

I think your wording is a bit misleading:
allow doesn't assume that an object responds to a message, it is explicitly required. The "assume" part is about the method getting called. It might or might not get called, but when it does, you want it to return "The RSpec book"

It's the same with expect: You don't expect what the call returns, you expect the call itself - meaning that you want your test to fail if the call doesn't happen in your subject under test. And when it actually gets called, you want it to return precisely "The RSpec Book".

It's a subtle but important distinction.

over 1 year ago ·