【问题标题】:Rspec tests for administrative 'delete' links fail. Michael Hartl's ROR 3.2 Tutorial - Chapter 9.4.2管理“删除”链接的 Rspec 测试失败。 Michael Hartl 的 ROR 3.2 教程 - 第 9.4.2 章
【发布时间】:2012-05-26 14:40:22
【问题描述】:

我正在关注 Michael 的 ROR 教程并创建用户身份验证系统。有一个管理员权限,允许用户删除其他用户。以特权管理员用户身份登录时,用户列表页面上会出现特殊的“删除”链接。 我的应用运行良好,但 rspec 测试因我不知道的原因而失败。

我已经将测试分离到另一个文件spec/requests/sat_spec.rb 并且我正在尝试使用 pry gem 来调试它,但到目前为止没有成功。

describe "delete links" do
  describe "as admin user" do
    let(:admin) { FactoryGirl.create(:admin) }
    before do
      sign_in admin
      visit users_path
      binding.pry          
    end
  it { should have_link('delete', href: user_path(User.first)) }

  it "should be able to delete another user" do
    expect { click_link('delete') }.to change(User, :count).by(-1)
  end    
end

测试失败:

1) separated admin tests delete links as admin user 
 Failure/Error: it { should have_link('delete', href: user_path(User.first)) }
   expected link "delete" to return something
 # ./spec/requests/sat_spec.rb:25:in `block (4 levels) in <top (required)>'

2) separated admin tests delete links as admin user should be able to delete another user
 Failure/Error: expect { click_link('delete') }.to change(User, :count).by(-1)
 Capybara::ElementNotFound:
   no link with title, id or text 'delete' found
 # (eval):2:in `click_link'
 # ./spec/requests/sat_spec.rb:28:in `block (5 levels) in <top (required)>'
 # ./spec/requests/sat_spec.rb:28:in `block (4 levels) in <top (required)>'

这里的问题可能是什么,或者更重要的是如何调试它?

你可以在这里 fork 我的代码https://github.com/tomek-rusilko/miniatury_katalog_2

【问题讨论】:

    标签: ruby-on-rails rspec capybara railstutorial.org


    【解决方案1】:

    您希望您的/users 页面包含旁边带有“删除”链接的用户列表。但是您没有用简单的用户填充您的 TEST 数据库。它只包含一个用户,即管理员。但是根据您的users/_user.html.erb,这种类型的用户没有“删除”链接。因此,请添加至少一个用户创建语句,然后重试。

    【讨论】:

    • 天哪,这太明显了!我觉得很愚蠢 :D 非常感谢。在解决问题之前输入简单的FactoryGirl.create(:user)。还有另一件事弹出:为什么FactoryGirl.create(:user) 有效但let(:user) { FactoryGirl.create(:user) } 无效?
    • let 被延迟评估:它的块在你使用 user "variable" 之前不会被调用。如果您希望立即调用您的块,请改用let!(带有感叹号)。但我建议您将FactoryGirl.create(:user) 放入before 块中。
    • 是的,这正是我所做的:before(:all) { 5.times { FactoryGirl.create(:user) } }; after(:all) { User.delete_all }。再次感谢您的帮助。
    【解决方案2】:
    let(:admin) { FactoryGirl.create(:admin) }
    

    这很好,因为你有(在 spec/factories.rb 中)

    factory :admin do
      admin true
    end
    

    但与此同时,在 models/user.rb 中:

    attr_accessible :name, :email, :password, :password_confirmation
    

    我敢打赌,工厂女孩正在使用批量赋值来设置 :admin => true,然后被 attr_accessible 删除。

    但更重要的是,你如何调试它?通过询问“发生了什么?”和“我期望会发生什么?”及其变化,直到你发现两个问题的答案在中间相遇。在这种情况下,我要开始的问题是:是什么导致链接显示?我在规范中设置的模型是否如此?规范是否达到了我期望的页面?当我用浏览器点击页面时,模型的行为是否与规范中的一样?

    但所有这些都只是“发生了什么?”的变体。和“我预计会发生什么?”

    【讨论】:

    • 我不完全知道 FactoryGirls 是如何处理它的,并且 admin 属性设置正确。这是另一个有趣的问题。无论如何,情况并非如此(见上文),但感谢您的帮助和合理的建议 - 我正在写下这些调试问题并将其固定在我的墙上:)
    • 好的,工厂绕过 attr_accessible 是设计使然
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多