what is wrong with this spec file

69 views
Skip to first unread message

Roelof Wobben

unread,
Jul 22, 2014, 2:23:07 AM7/22/14
to rs...@googlegroups.com
Hello,

I do still follow the Hartl tutorial.
Am at chapter 6 and according to the manual the test schould be successfull but I see these error messages:

Failures:                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                    
  1) User when password doesn't match confirmation return value of authenticate method with valid password                                                                                                                                          
     Failure/Error: it { should eq found_user.authenticate(@user.password) }                                                                                                                                                                        
     NoMethodError:                                                                                                                                                                                                                                 
       undefined method `authenticate' for nil:NilClass                                                                                                                                                                                             
     # ./spec/models/user_spec.rb:91:in `block (5 levels) in <top (required)>'     


Roelof

Javix

unread,
Jul 22, 2014, 4:15:41 AM7/22/14
to rs...@googlegroups.com
The error comes from the lien 91.

let(:found_user) { User.find_by(email: @user.email) }

Try to replace it as follows:

let(:found_user) { User.find_by_email(@user.email) 

Aaron Kromer

unread,
Jul 22, 2014, 10:06:17 AM7/22/14
to rs...@googlegroups.com

User.find_by(email: @user.email) is valid depending which version of Rails you are on; I believe Rails 4.x supports this format. My guess is that your user isn’t valid and thus does not save. Change line 87 to use save!:

before { @user.save! }


--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/d945fb01-2370-4b03-9460-3b3801ecad74%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Javix

unread,
Jul 22, 2014, 10:13:54 AM7/22/14
to rs...@googlegroups.com


On Tuesday, July 22, 2014 8:23:07 AM UTC+2, Roelof Wobben wrote:
@Aaron: as of his gemfile he uses 4.1.4. I don't  think save! could solve that because the previous example pass (line 20):

it { should be_valid }

The problem is that he is callilng authenticate on Nil.

Aaron Kromer

unread,
Jul 22, 2014, 1:05:40 PM7/22/14
to rs...@googlegroups.com

This is one reason I personally dislike this style of specs combined with AR hooks. It makes more difficult than necessary to troubleshoot.

As @javix pointed out, line 20 has:

it { should be_valid }

At this point the subject is what is defined on line 11:

subject { @user }

The ivar @user is defined in the before block on line 5:

before do
  @user = User.new(name: "Example User", email: "us...@example.com",
                   password: "foobar", password_confirmation: "foobar")

end

However, when the spec on line 91 runs it calls save in the before block on line 87:

before { @user.save }

By using save! it raises an error and confirms that the model was invalid. Here’s the error:

Failure/Error: before { @user.save! }
ActiveRecord::RecordInvalid:
  Validation failed: Password confirmation doesn't match Password

Dumping the attributes of @user shows there is a mismatch in the password:

{
  password: "foobar",
  password_confirmation: "mismatch",
}

This is happening because there is an additional before hook that runs defined on line 87. On a visual inspection, it doesn’t appear that it is initially related because the indenting is out of sync. The end on line 84 really applies to the describe on line 81.



--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.

Serguei Cambour

unread,
Jul 22, 2014, 4:57:45 PM7/22/14
to rs...@googlegroups.com
@Aaron: Well done ! I haven’t pick up the indention of do-end block.
--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/3j266FPKVy4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.

To post to this group, send email to rs...@googlegroups.com.

Roelof Wobben

unread,
Jul 23, 2014, 8:08:46 AM7/23/14
to rs...@googlegroups.com
hello,

I did add a end on rule 80 but still the test fail. Im now on holidays for 2 weeks and will look at this topic after my holidays,

Op dinsdag 22 juli 2014 22:57:45 UTC+2 schreef Javix:

Aaron Kromer

unread,
Jul 23, 2014, 11:28:23 AM7/23/14
to rs...@googlegroups.com

You’ll need to provide more details. Fixing that end worked for me.



Roelof Wobben

unread,
Jul 23, 2014, 2:02:12 PM7/23/14
to rs...@googlegroups.com

When I change it to :

 describe "when password doesn't match confirmation" do
    before { @user.password_confirmation = "mismatch" }
    it { should_not be_valid }
 
   describe "with a password that's too short" do
    before { @user.password = @user.password_confirmation = "a" * 5 }
    it { should be_invalid }
  end

I still see the old error
Also when I change the indention so it matches the second it.

Roelof
Op woensdag 23 juli 2014 17:28:23 UTC+2 schreef Aaron Kromer:

Aaron Kromer

unread,
Jul 23, 2014, 4:03:47 PM7/23/14
to rs...@googlegroups.com

That’s still missing an end:

describe "when password doesn't match confirmation" do
  before { @user.password_confirmation = "mismatch" }
  it { should_not be_valid }
# <---- No `end`


describe "with a password that's too short" do
  before { @user.password = @user.password_confirmation = "a" * 5 }
  it { should be_invalid }
end

Roelof Wobben

unread,
Jul 24, 2014, 8:52:37 AM7/24/14
to rs...@googlegroups.com
thanks,

problem solved,

Another question:

Aaron have said he do not like this sort of spec files.
What is a better style hen and what are AR's

Roelof

Op woensdag 23 juli 2014 22:03:47 UTC+2 schreef Aaron Kromer:

Serguei Cambour

unread,
Jul 24, 2014, 9:01:54 AM7/24/14
to rs...@googlegroups.com
You can replace the short version:

it { should_not be_valid }

with the more expisite one:

it "should not be valid" do
expect(@user).not_to be_valid
end



Aaron Kromer

unread,
Jul 25, 2014, 12:06:56 PM7/25/14
to rs...@googlegroups.com

AR = “ActiveRecord”

My comment was more simply just a personal style preference. There is no one correct way to write specs.

Personally, I do not like specs which modify variables or helpers defined in different scopes via before blocks. This leads to very confusing, “where was this defined? where was it modified?” questions and debugging sessions.

This is just my 2cents and take it with several grains of salt, but I would consider writing the spec this way: https://gist.github.com/cupakromer/fc5ccd67714c878dd5d8



Reply all
Reply to author
Forward
0 new messages