Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow vs Stub, what's the difference?

Tags:

ruby

rspec

What is the difference between the following lines of (rspec) code and regardless if they are the same or different, when should you use one instead of the other?

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

versus

book = double("book")
book.stub(:title).and_return("The RSpec Book")
like image 330
CharlesHorse Avatar asked Aug 12 '13 05:08

CharlesHorse


People also ask

What is stub in Rails?

In RSpec, a stub is often called a Method Stub, it's a special type of method that “stands in” for an existing method, or for a method that doesn't even exist yet. Here is the code from the section on RSpec Doubles − class ClassRoom def initialize(students) @students = students End def list_student_names @students.

What is the difference between stubs and mocks in Ruby testing?

The difference between mocks and stubs A Test Stub is a fake thing you stick in there to trick your program into working properly under test. A Mock Object is a fake thing you stick in there to spy on your program in the cases where you're not able to test something directly.

What is allow in RSpec?

Use the allow method with the receive matcher on a test double or a real. object to tell the object to return a value (or values) in response to a given. message. Nothing happens if the message is never received.


1 Answers

There are 2 differences but the result is exactly the same. Both are in regards to the rspec mocks/expectations syntax.

  1. Use of #allow instead of #stub method. First case uses the new rspec syntax introduced this year. This is now the preferred way of using rspec. Altough the old syntax isn't deprecated, it will probably be disabled by default in rspec3. More info on this topic from the maintainer of rspec: http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3

  2. Use of block instead of #and_return to define the returning value. This has nothing to do with the mentioned syntax change; both approaches have been available for quite a while (since rspec 1). It is more appropriate to use the #and_return method, since it is (a) the default way, (b) more readable and (c) comes without any runtime overhead. The second approach using block is usually reserved to the corner cases, when you wish to return something of more dynamic nature - not a constant, but some kind of calculation.

The answer to your question would be to use combination of both:

  • use the #allow instead of #stub
  • use #and_return instead of block, unless you need to return dynamically calculated value

E.g.:

book = double('book')
allow(book).to receive(:title).and_return('The RSpec Book')
like image 166
jurglic Avatar answered Oct 11 '22 03:10

jurglic