如何在Rspec / Capybara测试中访问FactoryGirl生成的用户的虚拟属性?

时间:2015-08-08 15:07:37

标签: ruby-on-rails testing rspec factory-bot

在教自己Ruby和Rails时,我目前正在建立一个基于Hartl tutorial的用户系统;此时的主要区别是我用Rspec / Capybara而不是TestUnit测试它。到目前为止,大多数事情都相当简单,但我在测试密码重置时遇到了这个问题。

当我手动测试密码重置时,它们完全按预期工作。因此,我很确定问题出在Rspec,Capybara和FactoryGirl之间。

失败的规范代码是我想访问忘记密码的链接:

# password_resets_spec.rb
visit(edit_password_reset_path(spec_user.reset_token, email: spec_user.email))

它给了我:

  

的ActionController :: UrlGenerationError:   没有路由匹配{:action =>" edit",:controller =>" password_resets",:email =>" john2@example.com",   :format => nil,:id => nil}缺少必需的键:[:id]

密码重置是(部分)资源,其ID是用户的reset_token

spec_user由FactoryGirl生成:

#password_resets_spec.rb
let(:spec_user){ FactoryGirl.create :user }

相关的:user工厂没有设置reset_token但是当我尝试使用的时候,重置表格没有正确设置令牌,并且没有匹配生成的摘要。以下是设置两者的代码:

# user.rb
def create_reset_digest
  self.reset_token = User.new_token
  update_attribute(:reset_digest, User.digest(reset_token))
  update_attribute(:reset_sent_at, Time.zone.now)
end

我可以通过使用设置reset_token的工厂来绕过上述错误,但是用于路径的令牌与保存的摘要不匹配,并且测试的下一步失败。 / p>

到目前为止,我的结论是我误解了虚拟属性的处理方式,因为在将摘要保存到数据库时,令牌是虚拟的。我怀疑我在规范中获得的reset_token与我生成摘要的路径不同,不知怎的。

任何帮助了解此处的内容都将非常感谢! :)

1 个答案:

答案 0 :(得分:1)

您收到路由错误,因为reset_token没有值;在这种情况下你的身份。

您可以在工厂创建的对象上设置/分配虚拟属性。只需将值传递给工厂:

let(:spec_user){ FactoryGirl.create :user,  reset_token: "some value"}

但是,对于您的用例,我猜测您还需要散列值在数据库中。 pasword_resets#edit可能通过对传入的reset_token进行哈希来查找用户记录。

所以,在您的规范中:

require 'spec_helper'

describe "PasswordResets" do
  describe "#edit" do
    it "looks up the user and provides a form to reset the password" do
      # Generate the token in advance, so you can set the digest on the user
      reset_token = User.new_token
      # Create your user with the digest
      spec_user = FactoryGirl.create(:user, reset_token: reset_token, reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
      # Now visit path with an actual value for reset_tokeb
      visit(edit_password_reset_path(spec_user.reset_token, email: spec_user.email))
    end
  end
end