Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Doc changes #89

merged 2 commits into from

2 participants


I found the README a bit hard to read on github without syntax highlighting.


This README has to look good on as well as here on github. I'll be glad to merge this as soon as supports github flavored markdown (which I believe is part of the next yard release, so that might be very soon).


Looks like GFM is working on I'm going to go ahead and merge this, but if it's not working yet after all, I'll be rolling it back. Let's see ...

@dchelimsky dchelimsky merged commit 3e89723 into rspec:master

Looks like it's OK on Thanks for the patch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 101 additions and 65 deletions.
  1. +101 −65
@@ -15,7 +15,9 @@ A Test Double is an object that stands in for a real object in a test.
RSpec creates test doubles that support method stubs and message
- book = double("book")
+book = double("book")
## Method Stubs
@@ -23,25 +25,33 @@ A method stub is an implementation that returns a pre-determined value. Method
stubs can be declared on test doubles or real objects using the same syntax.
rspec-mocks supports 3 forms for declaring method stubs:
- book.stub(:title) { "The RSpec Book" }
- book.stub(:title => "The RSpec Book")
- book.stub(:title).and_return("The RSpec Book")
+book.stub(:title) { "The RSpec Book" }
+book.stub(:title => "The RSpec Book")
+book.stub(:title).and_return("The RSpec Book")
You can also use this shortcut, which creates a test double and declares a
method stub in one statement:
- book = double("book", :title => "The RSpec Book")
+book = double("book", :title => "The RSpec Book")
The first argment is a name, which is used for documentation and appears in
failure messages. If you don't care about the name, you can leave it out,
making the combined instantiation/stub declaration very terse:
- double(:foo => 'bar')
+double(:foo => 'bar')
This is particularly nice when providing a list of test doubles to a method
that iterates through them:
- order.calculate_total_price(stub(:price => 1.99),stub(:price => 2.99))
+order.calculate_total_price(stub(:price => 1.99),stub(:price => 2.99))
## Consecutive return values
@@ -49,16 +59,20 @@ When a stub might be invoked more than once, you can provide additional
arguments to `and_return`. The invocations cycle through the list. The last
value is returned for any subsequent invocations:
- die.stub(:roll).and_return(1,2,3)
- die.roll # => 1
- die.roll # => 2
- die.roll # => 3
- die.roll # => 3
- die.roll # => 3
+die.roll # => 1
+die.roll # => 2
+die.roll # => 3
+die.roll # => 3
+die.roll # => 3
To return an array in a single invocation, declare an array:
- team.stub(:players).and_return([stub(:name => "David")])
+team.stub(:players).and_return([stub(:name => "David")])
## Message Expectations
@@ -66,10 +80,12 @@ A message expectation is an expectation that the test double will receive a
message some time before the example ends. If the message is received, the
expectation is satisfied. If not, the example fails.
- validator = double("validator")
- validator.should_receive(:validate).with("02134")
- zipcode ="02134", validator)
- zipcode.valid?
+validator = double("validator")
+zipcode ="02134", validator)
## Nomenclature
@@ -94,21 +110,25 @@ behaviour in the context of a test. This technique is very common in Ruby
because we often see class objects acting as global namespaces for methods.
For example, in Rails:
- person = double("person")
- Person.stub(:find) { person }
+person = double("person")
+Person.stub(:find) { person }
In this case we're instrumenting Person to return the person object we've
defined whenever it receives the `find` message. We can do this with any
object in a system because rspec-mocks adds the `stub` and `should_receive`
methods to every object. When we use either, RSpec replaces the method
-we're stubbing or mocking with it's own test-double-like method. At the
+we're stubbing or mocking with its own test-double-like method. At the
end of the example, RSpec verifies any message expectations, and then
restores the original methods.
## Expecting Arguments
- double.should_receive(:msg).with(*args)
- double.should_not_receive(:msg).with(*args)
## Argument Matchers
@@ -122,33 +142,39 @@ you are free to create your own custom RSpec::Matchers.
rspec-mocks also adds some keyword Symbols that you can use to
specify certain kinds of arguments:
- double.should_receive(:msg).with(no_args())
- double.should_receive(:msg).with(any_args())
- double.should_receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can any kind of Numeric
- double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can true or false
- double.should_receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
- double.should_receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
- double.should_receive(:msg).with(1, ducktype(:abs, :div), "b")
- #2nd argument can be object that responds to #abs and #div
+double.should_receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can any kind of Numeric
+double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can true or false
+double.should_receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
+double.should_receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
+double.should_receive(:msg).with(1, ducktype(:abs, :div), "b")
+ #2nd argument can be object that responds to #abs and #div
## Receive Counts
- double.should_receive(:msg).once
- double.should_receive(:msg).twice
- double.should_receive(:msg).exactly(n).times
- double.should_receive(:msg).at_least(:once)
- double.should_receive(:msg).at_least(:twice)
- double.should_receive(:msg).at_least(n).times
- double.should_receive(:msg).at_most(:once)
- double.should_receive(:msg).at_most(:twice)
- double.should_receive(:msg).at_most(n).times
- double.should_receive(:msg).any_number_of_times
## Ordering
- double.should_receive(:msg).ordered
- double.should_receive(:other_msg).ordered
- #This will fail if the messages are received out of order
+ #This will fail if the messages are received out of order
## Setting Reponses
@@ -156,30 +182,36 @@ Whether you are setting a message expectation or a method stub, you can
tell the object precisely how to respond. The most generic way is to pass
a block to `stub` or `should_receive`:
- double.should_receive(:msg) { value }
+double.should_receive(:msg) { value }
When the double receives the `msg` message, it evaluates the block and returns
the result.
- double.should_receive(:msg).and_return(value)
- double.should_receive(:msg).exactly(3).times.and_return(value1, value2, value3)
- # returns value1 the first time, value2 the second, etc
- double.should_receive(:msg).and_raise(error)
- #error can be an instantiated object or a class
- #if it is a class, it must be instantiable with no args
- double.should_receive(:msg).and_throw(:msg)
- double.should_receive(:msg).and_yield(values,to,yield)
- double.should_receive(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time)
- # for methods that yield to a block multiple times
+double.should_receive(:msg).exactly(3).times.and_return(value1, value2, value3)
+ # returns value1 the first time, value2 the second, etc
+ #error can be an instantiated object or a class
+ #if it is a class, it must be instantiable with no args
+ # for methods that yield to a block multiple times
Any of these responses can be applied to a stub as well
- double.stub(:msg).and_return(value)
- double.stub(:msg).and_return(value1, value2, value3)
- double.stub(:msg).and_raise(error)
- double.stub(:msg).and_throw(:msg)
- double.stub(:msg).and_yield(values,to,yield)
- double.stub(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time)
+double.stub(:msg).and_return(value1, value2, value3)
## Arbitrary Handling
@@ -188,16 +220,20 @@ particular problem you are trying to solve. Imagine that you expect the message
to come with an Array argument that has a specific length, but you don't care
what is in it. You could do this:
- double.should_receive(:msg) do |arg|
- arg.size.should eq(7)
- end
+double.should_receive(:msg) do |arg|
+ arg.size.should eq(7)
## Combining Expectation Details
Combining the message name with specific arguments, receive counts and responses
you can get quite a bit of detail in your expectations:
- double.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError)
+double.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError)
While this is a good thing when you really need it, you probably don't really
need it! Take care to specify only the things that matter to the behavior of
Something went wrong with that request. Please try again.