should
and should_not
syntax
From the beginning ::RSpec::Expectations
provided should
and should_not
methods
to define expectations on any object. In version 2.11 expect
method was
introduced which is now the recommended way to define expectations on an object.
Why switch over from should
to expect
Fix edge case issues
should
and should_not
work by being added to every object. However, RSpec
does not own every object and cannot ensure they work consistently on every object.
In particular, they can lead to surprising failures when used with BasicObject-subclassed
proxy objects.
expect
avoids these problems altogether by not needing to be available on all objects.
Unification of block and value syntaxes
Before version 2.11 expect
was just a more readable alternative for block
expectations. Since version 2.11 expect
can be used for both block and value
expectations.
expect(actual).to eq(expected)
expect { ... }.to raise_error(ErrorClass)
See http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax For a detailed explanation
One-liners
The one-liner syntax supported by
rspec-core uses should
even when
config.syntax = :expect
. It reads better than the alternative, and does not
require a global monkey patch:
describe User do
it { should validate_presence_of :email }
end
It can also be expressed with the is_expected
syntax:
describe User do
it { is_expected.to validate_presence_of :email }
end
Using either expect
or should
or both
By default, both expect
and should
syntaxes are available. In the future,
the default may be changed to only enable the expect
syntax.
If you want your project to only use any one of these syntaxes, you can configure it:
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect # disables `should`
# or
c.syntax = :should # disables `expect`
# or
c.syntax = [:should, :expect] # default, enables both `should` and `expect`
end
end
See RSpec::Expectations::Syntax#expect for more information.
Usage
The should
and should_not
methods can be used to define expectations on any
object.
actual.should eq expected
actual.should be > 3
[1, 2, 3].should_not include 4
Using Built-in matchers
Equivalence
actual.should eq(expected) # passes if actual == expected
actual.should == expected # passes if actual == expected
actual.should_not eql(expected) # passes if actual.eql?(expected)
Note: we recommend the eq
matcher over ==
to avoid Ruby's "== in a
useless context" warning when the ==
matcher is used anywhere but the
last statement of an example.
Identity
actual.should be(expected) # passes if actual.equal?(expected)
actual.should_not equal(expected) # passes if actual.equal?(expected)
Comparisons
actual.should be > expected
actual.should be >= expected
actual.should be <= expected
actual.should be < expected
actual.should be_within(delta).of(expected)
Regular expressions
actual.should match(/expression/)
actual.should =~ /expression/
Types/classes
actual.should be_an_instance_of(expected)
actual.should_not be_a_kind_of(expected)
Truthiness
actual.should be_true # passes if actual is truthy (not nil or false)
actual.should be_false # passes if actual is falsy (nil or false)
actual.should be_nil # passes if actual is nil
Predicate matchers
actual.should be_xxx # passes if actual.xxx?
actual.should_not have_xxx(:arg) # passes if actual.has_xxx?(:arg)
Ranges (Ruby >= 1.9 only)
(1..10).should cover(3)
Collection membership
actual.should include(expected)
actual.should start_with(expected)
actual.should end_with(expected)
Examples
[1,2,3].should include(1)
[1,2,3].should include(1, 2)
[1,2,3].should start_with(1)
[1,2,3].should start_with(1,2)
[1,2,3].should end_with(3)
[1,2,3].should end_with(2,3)
{:a => 'b'}.should include(:a => 'b')
"this string".should include("is str")
"this string".should start_with("this")
"this string".should end_with("ring")