在实例方法中设置属性时,Capybara会抛出错误,因为它未定义,但为什么呢?

时间:2013-12-26 21:41:13

标签: ruby-on-rails rspec capybara

我正在使用Capybara进行集成测试,我注意到当您尝试在实例方法中设置属性时会抛出错误,例如:

def set_password_reset_token
  self.password_reset_token = self.class.generate_token
end

其中password_reset_token是attr_accessible的数据库列。这个实例方法工作正常,但是当使用Capybara进行测试时,例如:

it "updates the user password when confirmation matches" do
  user = FactoryGirl.create(:user)
  user.set_password_reset_token
  visit edit_password_reset_url(user.password_reset_token)       
  fill_in "password", with: "123456"
  click_button "Update Password"
  expect(page).to have_content("Password has been reset")
end

发生以下故障:

PasswordResets
  updates the user password when confirmation matches (FAILED - 1)

Failures:

  1) PasswordResets updates the user password when confirmation matches
     Failure/Error: user.set_password_reset_token
     NoMethodError:
       undefined method `password_reset_token=' for #<User:0x007fd237d31e20>
     # ./app/models/user.rb:107:in `set_password_reset_token'
     # ./spec/features/password_resets_spec.rb:25:in `block (2 levels) in <top (required)>'

Finished in 0.19426 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/password_resets_spec.rb:23 # PasswordResets updates the user password when confirmation matches

确实如此,没有password_reset_token =方法。 User.instance_methods.include?(:password_reset_token =)返回false。但是,在实际执行代码时,该属性设置正确。我很好奇为什么会出现错误以及可以通过什么来使测试通过。 Capybara是否通过调用instance_methods.include来测试该方法?为什么它不执行代码并查看是否出现错误?

2 个答案:

答案 0 :(得分:1)

attr_accessor,而不是attr_accessible,会自动定义getter和setter方法。您可以在此SO Post中了解有关它的更多信息。

因此,在您的情况下,您可以将password_reset_token添加到attr_accessor或将set_reset_password_token更改为:

def set_password_reset_token
  password = self.class.generate_token
  self.update_attribute(:password_reset_token, password)
end

答案 1 :(得分:0)

发生此错误是因为尚未迁移测试环境。迁移测试环境后,测试全部通过。