Let’s look at how this syntax works for RSpec in the context of the Ruby Language.
http://rspec.info/documentation/3.2/rspec-expectations/RSpec/Matchers.html#change-instance_method
https://www.relishapp.com/rspec/rspec-expectations/v/3-2/docs/built-in-matchers/change-matcher
expect {
team.add_player(player)
}.to change(roster, :count)
expect {
team.add_player(player)
}.to change { roster.count }
-
expect
is a method call that takes a block. The block can use either{}
ordo end
as the bock will be bound to theexpect
method calll regardless. -
The result of calling
expect
with a block is then called with theto
(ornot_to
) method, passing in either 2 parameters or a block. From the docs is this incredibly important statement:
You can either pass receiver and message, or a block, but not both.
-
When pass a block to
change
, it’s critical to use{}
syntax and NOTdo end
syntax as the lower precedence of thedo end
will result in the block being bound to the call toto
ornot_to
rather thanchange
. -
Definitely use spaces around the
{}
as they look too much like()
parens.
Take a look at the samples below. Consider how you could switch between the two syntaxes.
I created a video where I walk through this example:
Some examples of the syntax:
expect {
team.add_player(player)
}.to change(roster, :count)
expect {
team.add_player(player)
}.to change(roster, :count).by(1)
expect {
team.add_player(player)
}.to change(roster, :count).by_at_least(1)
expect {
team.add_player(player)
}.to change(roster, :count).by_at_most(1)
string = "string"
expect {
string.reverse!
}.to change { string }.from("string").to("gnirts")
string = "string"
expect {
string
}.not_to change { string }.from("string")
expect {
person.happy_birthday
}.to change(person, :birthday).from(32).to(33)
expect {
employee.develop_great_new_social_networking_app
}.to change(employee, :title).from("Mail Clerk").to("CEO")
expect {
doctor.leave_office
}.to change(doctor, :sign).from(/is in/).to(/is out/)
user = User.new(:type => "admin")
expect {
user.symbolize_type
}.to change(user, :type).from(String).to(Symbol)