2

I am running Rails 3.2.1 and rails-rspec 2.8.1....When I run the test for resetting a user's password, it seems that reloading the user object doesn't load the new password attribute....

Here is the code for my test:

 describe "Reset password page" do
    let(:teacher) { FactoryGirl.create(:teacher, :email=>"jane@gmail.com")}
    let(:old_password) { teacher.password }
    before do
      visit reset_password_form_path
      fill_in "Email", with: teacher.email
      click_button "Reset Password"
    end
    it { should have_content('Your new password has been emailed to the address you provided.')}
    specify { Teacher.find_by_email("jane@gmail.com").password.should_not == old_password }
    ## specify { teacher.reload.password.should_not == old_password }  ##THIS FAILS
  end

specify { teacher.reload.password.should_not == old_password } FAILS but specify { Teacher.find_by_email("jane@gmail.com").password.should_not == old_password } PASSES

So this tells me the password is being saved correctly, but not being reloaded...any ideas why? I am using the Rails 3.2.x "has_secure_password" method for rolling the login/password features. This means a password_digest is what gets saved to the database, and password is a virtual attribute (I think).

  • I had the same issue with `reload`, didn't work inside the `should`: http://stackoverflow.com/questions/10504505/testing-datamapper-models-with-rspec – Samy Dindane May 16 '12 at 21:18
  • 2
    in your example, the reload works perfectly, you should just use should_not – apneadiving May 16 '12 at 21:20
  • @Samy Dindane, I am confused by your answer at [10504505](http://stackoverflow.com/questions/10504505/testing-datamapper-models-with-rspec) because isn't my specify{teacher.reload...} line equivalent to snippet.reload.title.should == 'goodbye'?? –  May 16 '12 at 21:41
  • Oh sorry man. I was a bit confused when I posted the first comment. Please never mind it. :) – Samy Dindane May 16 '12 at 21:47
  • @apneadiving, sorry, there was a typo - with "should_not" the .reload line fails, that's why I was so puzzled; I've corrected the typo in the original post –  May 16 '12 at 21:49
  • Are you using something like Capybara to drive a browser? If so, you can't use transactional fixtures, which may be turned on in your spec_helper. With transactional fixtures, the code in rspec can't see the database changes made by your browser. – Rob Davis May 18 '12 at 15:08

1 Answers1

1

Just understood: let blocks are not loaded till you summon them.

So, because you didn't use old_password anywhere before:

teacher.reload.password.should_not == old_password

Is equivalent to:

teacher.reload.password.should_not == teacher.reload.password

That's why it just can't fail!

If you want it to fail correctly:

old_password #because it's triggered, the value is set and won't be set again
teacher.reload.password.should_not == old_password

Edit:

describe "Reset password page" do
  let(:teacher) { FactoryGirl.create(:teacher, :email=>"jane@gmail.com")}

  before do
    @old_password = teacher.password
    visit reset_password_form_path
    fill_in "Email", with: teacher.email
    click_button "Reset Password"
  end

  specify { teacher.reload.password.should_not == @old_password }
end
apneadiving
  • 114,565
  • 26
  • 219
  • 213
  • so here is part of the re-written test: `let(:teacher) { FactoryGirl.create(:teacher, :email=>"jane@gmail.com", :password=>"foobar",:password_confirmation=>"foobar")} let(:old_password) { "foobar" } before do old_password...` specify{teacher.reload...} still fails even when I call old_password in the before block...At this point, I'm thinking it may be because "password" is a virtual attribute for the teacher model (a password_digest is what actually gets saved to the database) and somehow that's causing it just to reload the FactoryGirl original password. –  May 16 '12 at 23:18
  • Instead of using an instance variable, you can use `let!(:old_password) { ... }` to execute a let immediately instead of lazily (note the exclamation point). – Rob Davis May 18 '12 at 15:10
  • @RobDavis: nice remark. Still seems weird to use let in this case – apneadiving May 18 '12 at 17:32