RSpec Expectations Build Status Code Climate

RSpec::Expectations lets you express expected outcomes on an object in an example.

expect(.balance).to eq(Money.new(37.42, :USD))

Install

If you want to use rspec-expectations with rspec, just install the rspec gem and RubyGems will also install rspec-expectations for you (along with rspec-core and rspec-mocks):

gem install rspec

If you want to use rspec-expectations with another tool, like Test::Unit, Minitest, or Cucumber, you can install it directly:

gem install rspec-expectations

Basic usage

Here’s an example using rspec-core:

ruby RSpec.describe Order do it "sums the prices of the items in its line items" do order = Order.new order.add_entry(LineItem.new(:item => Item.new( :price => Money.new(1.11, :USD) ))) order.add_entry(LineItem.new(:item => Item.new( :price => Money.new(2.22, :USD), :quantity => 2 ))) expect(order.total).to eq(Money.new(5.55, :USD)) end end

The describe and it methods come from rspec-core. The Order, LineItem, Item and Money classes would be from your code. The last line of the example expresses an expected outcome. If order.total == Money.new(5.55, :USD), then the example passes. If not, it fails with a message like:

expected: #<Money @value=5.55 @currency=:USD>
     got: #<Money @value=1.11 @currency=:USD>

Built-in matchers

Equivalence

ruby expect(actual).to eq(expected) # passes if actual == expected expect(actual).to eql(expected) # passes if actual.eql?(expected)

Note: The new expect syntax no longer supports the == matcher.

Identity

ruby expect(actual).to be(expected) # passes if actual.equal?(expected) expect(actual).to equal(expected) # passes if actual.equal?(expected)

Comparisons

ruby expect(actual).to be > expected expect(actual).to be >= expected expect(actual).to be <= expected expect(actual).to be < expected expect(actual).to be_within(delta).of(expected)

Regular expressions

ruby expect(actual).to match(/expression/)

Note: The new expect syntax no longer supports the =~ matcher.

Types/classes

ruby expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected expect(actual).to be_a(expected) # passes if actual.is_a?(expected) expect(actual).to be_an(expected) # an alias for be_a expect(actual).to be_a_kind_of(expected) # another alias

Truthiness

ruby expect(actual).to be_truthy # passes if actual is truthy (not nil or false) expect(actual).to be true # passes if actual == true expect(actual).to be_falsy # passes if actual is falsy (nil or false) expect(actual).to be false # passes if actual == false expect(actual).to be_nil # passes if actual is nil

Expecting errors

ruby expect { ... }.to raise_error expect { ... }.to raise_error(ErrorClass) expect { ... }.to raise_error("message") expect { ... }.to raise_error(ErrorClass, "message")

Expecting throws

ruby expect { ... }.to throw_symbol expect { ... }.to throw_symbol(:symbol) expect { ... }.to throw_symbol(:symbol, 'value')

Yielding

```ruby expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args

expect { b yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded
expect { b 5.tap(&b) }.to yield_with_args(5)
expect { b 5.tap(&b) }.to yield_with_args(Fixnum)
expect { b “a string”.tap(&b) }.to yield_with_args(/str/)

expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) ```

Predicate matchers

ruby expect(actual).to be_xxx # passes if actual.xxx? expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg)

Ranges (Ruby >= 1.9 only)

ruby expect(1..10).to cover(3)

Collection membership

```ruby expect(actual).to include(expected) expect(actual).to start_with(expected) expect(actual).to end_with(expected)

expect(actual).to contain_exactly(individual, items) # …which is the same as: expect(actual).to match_array(expected_array) ```

Examples

ruby expect([1, 2, 3]).to include(1) expect([1, 2, 3]).to include(1, 2) expect([1, 2, 3]).to start_with(1) expect([1, 2, 3]).to start_with(1, 2) expect([1, 2, 3]).to end_with(3) expect([1, 2, 3]).to end_with(2, 3) expect({:a => 'b'}).to include(:a => 'b') expect("this string").to include("is str") expect("this string").to start_with("this") expect("this string").to end_with("ring") expect([1, 2, 3]).to contain_exactly(2, 3, 1) expect([1, 2, 3]).to match_array([3, 2, 1])

should syntax

In addition to the expect syntax, rspec-expectations continues to support the should syntax:

ruby actual.should eq expected actual.should be > 3 [1, 2, 3].should_not include 4

See detailed information on the should syntax and its usage.

Compound Matcher Expressions

You can also create compound matcher expressions using and or or:

ruby expect(alphabet).to start_with("a").and end_with("z") expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")

Composing Matchers

Many of the built-in matchers are designed to take matchers as arguments, to allow you to flexibly specify only the essential aspects of an object or data structure. In addition, all of the built-in matchers have one or more aliases that provide better phrasing for when they are used as arguments to another matcher.

Examples

```ruby expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) )

expect { s = “barn” }.to change { s } .from( a_string_matching(/foo/) ) .to( a_string_matching(/bar/) )

expect([“barn”, 2.45]).to contain_exactly( a_value_within(0.1).of(2.5), a_string_starting_with(“bar”) )

expect([“barn”, “food”, 2.45]).to end_with( a_string_matching(“foo”), a_value > 2 )

expect([“barn”, 2.45]).to include( a_string_starting_with(“bar”) )

expect(:a => “food”, :b => “good”).to include(:a => a_string_matching(/foo/))

hash = { :a => { :b => [“foo”, 5], :c => { :d => 2.05 } } }

expect(hash).to match( :a => { :b => a_collection_containing_exactly( a_string_starting_with(“f”), an_instance_of(Fixnum) ), :c => { :d => (a_value < 3) } } )

expect { |probe| [1, 2, 3].each(&probe) }.to yield_successive_args( a_value < 2, 2, a_value > 2 ) ```

Usage outside rspec-core

You always need to load rspec/expectations even if you only want to use one part of the library:

ruby require 'rspec/expectations'

Then simply include RSpec::Matchers in any class:

```ruby class MyClass include RSpec::Matchers

def do_something(arg) expect(arg).to be > 0 # do other stuff end end ```

Also see