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.
allow
:
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.
expect
:
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 :).
Written by Vu Manh Cuong
Related protips
1 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.