[rspec-users] Can some one please explain why one of those two examples fails?

Mohamad El-Husseini husseini.mel at gmail.com
Thu Mar 15 12:46:12 UTC 2012


Thanks, Mike. I appreciate the explanation. It's tricky knowing what runs 
when, and what variable is in what scope. It seems like "code smell" to add 
an instance variable to the before block.

I don't understand what advantage one approach has over the other. What 
would you use, the first, that was broken, or the second?

On Tuesday, March 13, 2012 9:24:03 PM UTC-3, Mike Mazur wrote:
>
> Hi,
>
> On Wed, Mar 14, 2012 at 07:55, Mohamad El-Husseini
> <husseini.mel at gmail.com> wrote:
> > The following are what I believe two ways of doing the same thing. Only 
> the
> > first example fails, while the latter passes.
>
> In your failing example:
>
>    context "generates a unique password_reset_token each time" do
>       let(:user) { FactoryGirl.create(:user) }
>       before do
>         user.send_password_reset
>         last_token = user.password_reset_token
>         user.send_password_reset
>       end
>       its(:password_reset_token) { should_not == last_token }
>     end
>
> The `last_token` variable is in scope in the before block, but not in
> the its block. You can fix this by changing it to an instance
> variable:
>
>    context "generates a unique password_reset_token each time" do
>       let(:user) { FactoryGirl.create(:user) }
>       before do
>         user.send_password_reset
>         @last_token = user.password_reset_token
>         user.send_password_reset
>       end
>       its(:password_reset_token) { should_not == @last_token }
>     end
>
> Another gotcha is: what is the its expression making assertions on?
> The its method requires a subject to be defined.
>
> RSpec defines an implicit subject based on the described class. I
> imagine at the top of your .spec file you have something like:
>
>   describe User do
>     # stuff
>   end
>
> RSpec will generate a subject by calling `User.new`.
> `password_reset_token` is then called on this new user instance in the
> its block. You most certainly wanted to call `password_reset_token` on
> the user object defined by the `let` statement.
>
> So I think this should do the trick:
>
>    context "generates a unique password_reset_token each time" do
>       let(:user) { FactoryGirl.create(:user) }
>       subject { user }
>       before do
>         user.send_password_reset
>         @last_token = user.password_reset_token
>         user.send_password_reset
>       end
>       its(:password_reset_token) { should_not == @last_token }
>     end
>
> You can read more about RSpec's subject here:
>
>   https://www.relishapp.com/rspec/rspec-core/docs/subject
>
> Hope that helps,
> Mike
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20120315/79e4e690/attachment.html>


More information about the rspec-users mailing list