Skip to content

Commit

Permalink
Update README.md to use expect syntax.
Browse files Browse the repository at this point in the history
This fixes #300
  • Loading branch information
Thomas Holmes committed Jun 6, 2013
1 parent fbae36d commit 1f370af
Showing 1 changed file with 53 additions and 54 deletions.
107 changes: 53 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,23 @@ stubs can be declared on test doubles or real objects using the same syntax.
rspec-mocks supports 3 forms for declaring method stubs:

```ruby
book.stub(:title) { "The RSpec Book" }
book.stub(:title => "The RSpec Book")
book.stub(:title).and_return("The RSpec Book")
allow(book).to receive(:title) { "The RSpec Book" }
allow(book).to receive(: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:

```ruby
book = double("book", :title => "The RSpec Book")
book = double("book", title: "The RSpec Book")
```

The first argument 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:

```ruby
double(:foo => 'bar')
double(foo: 'bar')
```

This is particularly nice when providing a list of test doubles to a method
Expand All @@ -60,7 +59,7 @@ arguments to `and_return`. The invocations cycle through the list. The last
value is returned for any subsequent invocations:

```ruby
die.stub(:roll).and_return(1,2,3)
allow(die).to receive(:roll).and_return(1,2,3)
die.roll # => 1
die.roll # => 2
die.roll # => 3
Expand All @@ -71,7 +70,7 @@ die.roll # => 3
To return an array in a single invocation, declare an array:

```ruby
team.stub(:players).and_return([stub(:name => "David")])
allow(team).to receive(:players).and_return([double(name: "David")])
```

## Message Expectations
Expand All @@ -82,7 +81,7 @@ expectation is satisfied. If not, the example fails.

```ruby
validator = double("validator")
validator.should_receive(:validate).with("02134")
expect(validator).to receive(:validate) { "02134" }
zipcode = Zipcode.new("02134", validator)
zipcode.valid?
```
Expand Down Expand Up @@ -134,7 +133,7 @@ For example, in Rails:

```ruby
person = double("person")
Person.stub(:find) { person }
allow(Person).to receive(:find) { person }
```

In this case we're instrumenting Person to return the person object we've
Expand All @@ -143,7 +142,7 @@ expectation so that the example fails if `find` is not called:

```ruby
person = double("person")
Person.should_receive(:find) { person }
expect(Person).to receive(:find) { person }
```

We can do this with any object in a system because rspec-mocks adds the `stub`
Expand All @@ -155,15 +154,15 @@ expectations, and then restores the original methods.
## Expecting Arguments

```ruby
double.should_receive(:msg).with(*args)
double.should_not_receive(:msg).with(*args)
expect(double).to receive(:msg).with(*args)
expect(double).to_not receive(:msg).with(*args)
```

You can set multiple expectations for the same message if you need to:

```ruby
double.should_receive(:msg).with("A", 1, 3)
double.should_receive(:msg).with("B", 2, 4)
expect(double).to receive(:msg).with("A", 1, 3)
expect(double).to receive(:msg).with("B", 2, 4)
```

## Argument Matchers
Expand All @@ -179,81 +178,81 @@ rspec-mocks also adds some keyword Symbols that you can use to
specify certain kinds of arguments:

```ruby
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 be any kind of Numeric
double.should_receive(:msg).with(1, boolean(), "b") #2nd argument can be 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, duck_type(:abs, :div), "b")
expect(double).to receive(:msg).with(no_args())
expect(double).to receive(:msg).with(any_args())
expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b")
#2nd argument can be object that responds to #abs and #div
```

## Receive Counts

```ruby
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
expect(double).to receive(:msg).once
expect(double).to receive(:msg).twice
expect(double).to receive(:msg).exactly(n).times
expect(double).to receive(:msg).at_least(:once)
expect(double).to receive(:msg).at_least(:twice)
expect(double).to receive(:msg).at_least(n).times
expect(double).to receive(:msg).at_most(:once)
expect(double).to receive(:msg).at_most(:twice)
expect(double).to receive(:msg).at_most(n).times
expect(double).to receive(:msg).any_number_of_times
```

## Ordering

```ruby
double.should_receive(:msg).ordered
double.should_receive(:other_msg).ordered
expect(double).to receive(:msg).ordered
expect(double).to receive(:other_msg).ordered
#This will fail if the messages are received out of order
```

This can include the same message with different arguments:

```ruby
double.should_receive(:msg).with("A", 1, 3).ordered
double.should_receive(:msg).with("B", 2, 4).ordered
expect(double).to receive(:msg).with("A", 1, 3).ordered
expect(double).to receive(:msg).with("B", 2, 4).ordered
```

## Setting Responses

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`:
a block to `receive`:

```ruby
double.should_receive(:msg) { value }
expect(double).to receive(:msg) { value }
```

When the double receives the `msg` message, it evaluates the block and returns
the result.

```ruby
double.should_receive(:msg).and_return(value)
double.should_receive(:msg).exactly(3).times.and_return(value1, value2, value3)
expect(double).to receive(:msg).and_return(value)
expect(double).to 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)
expect(double).to 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)
expect(double).to receive(:msg).and_throw(:msg)
expect(double).to receive(:msg).and_yield(values,to,yield)
expect(double).to receive(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time)
# for methods that yield to a block multiple times
```

Any of these responses can be applied to a stub as well

```ruby
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)
allow(double).to receive(:msg).and_return(value)
allow(double).to receive(:msg).and_return(value1, value2, value3)
allow(double).to receive(:msg).and_raise(error)
allow(double).to receive(:msg).and_throw(:msg)
allow(double).to receive(:msg).and_yield(values,to,yield)
allow(double).to receive(:msg).and_yield(values,to,yield).and_yield(some,other,values,this,time)
```

## Arbitrary Handling
Expand All @@ -264,16 +263,16 @@ to come with an Array argument that has a specific length, but you don't care
what is in it. You could do this:

```ruby
double.should_receive(:msg) do |arg|
arg.size.should eq(7)
expect(double).to receive(:msg) do |arg|
expect(arg.size).to eq 7
end
```

If the method being stubbed itself takes a block, and you need to yield to it
in some special way, you can use this:

```ruby
double.should_receive(:msg) do |&arg|
expect(double).to receive(:msg) do |&arg|
begin
arg.call
ensure
Expand All @@ -290,7 +289,7 @@ the object responds to the message. You can use `and_call_original`
to achieve this:

```ruby
Person.should_receive(:find).and_call_original
expect(Person).to receive(:find).and_call_original
Person.find # => executes the original find method and returns the result
```

Expand All @@ -300,7 +299,7 @@ Combining the message name with specific arguments, receive counts and responses
you can get quite a bit of detail in your expectations:

```ruby
double.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError)
expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError)
```

While this is a good thing when you really need it, you probably don't really
Expand Down

0 comments on commit 1f370af

Please sign in to comment.