While going through Ruby On Rails Tutorial by Michael Hartl,in the section where the author writes integration test to validate his Signup page, he has used code spinet bellow. I got what the code does but couldn’t get my head around the ‘how’ part i.e. couldn’t understand order of execution.
expect { click_button "Create my account" }.not_to change(User, :count)
Can someone please explain the semantics of the above chain of methods and blocks and how they fit together?
You’d use
expect ... changeto verify that a particular method call changes — or does not change — some other value. In this case:will cause rspec to do the following:
User.countand note the value returned. (This can be specified as a receiver and a method name, like(User, :count)in your example, or as an arbitrary block of code, like{ User.count }.click_button "Create my account"which is a Capybara method that simulates a mouse click on a link.User.countagain.Other ways to use
expect ... change:Some docs are here.
How it does this is a bit arcane, and it’s not at all necessary to understand how it works in order to use it. A call to
expectis defining a structure for rspec to execute, using rspec’s own custom DSL and system of “matchers.” Gary Bernhardt has a rather neat screencast in which he argues that the mystery of rspec actually falls out naturally from a dynamic language like ruby. It’s not a good introduction to using rspec, but if you’re curious about how it all works, you might find it interesting.UPDATE
After seeing your comment on another answer, I’ll add a bit about the order of operations. The unintuitive trick is that it’s the matcher (
changein this case) that executes all of the blocks.expecthas a lambda,not_tois an alias forshould_notwhose job is to pass the lambda on to the matcher. The matcher in this case ischangewhich knows to execute its own argument once, then execute the lambda that it was passed (the one fromexpect), then run its own argument again to see if things changed. It’s tricky because the line looks like it should execute left to right, but since most of the pieces are just passing around blocks of code, they can and do shuffle them into whatever order makes the most sense to the matcher.I’m not an expert on the rspec internals, but that’s my understanding of the basic idea.