测试我为Rails教程应用程序编写的新用户锁定功能



我编写了Ruby on Rails教程的第9章,并添加了我自己的功能,以便在用户首次注册时锁定用户,以便管理员必须在新用户访问该站点之前进入并批准("解锁")他们的ID。 我添加了一个 :lock 布尔属性,它的工作方式就像 User 对象的 :admin 属性一样。 我现在一切都可以工作了,但是我无法为它编写一个简单的测试。 我将以下测试添加到 user_pages_spec.rb,就在层次结构"分页"下 - "作为管理员用户":

describe "as an admin user to unlock new users" do
    let(:admin) { FactoryGirl.create(:admin) }
    let(:locked_user) { FactoryGirl.create(:locked) }
    before do
      sign_in admin
      visit users_path
    end
    it { should have_link('unlock', href: user_path(locked_user)) }
    it { should_not have_link('unlock', href: user_path(admin)) }
end

为了支持创建"锁定"用户,将其添加到 factories.rb:

factory :locked do
    locked true
end

可以通过Firefox手动确认解锁链接是否显示,但是我仍然遇到以下故障:

  1) User pages index pagination as an admin user to unlock new users 
     Failure/Error: it { should have_link('unlock', href: user_path(locked_user)) }
       expected link "unlock" to return something
     # ./spec/requests/user_pages_spec.rb:64:in `block (5 levels) in <top (required)>'

我有兴趣知道 a) 为什么这会失败:),但也想知道 b) 如何调试这样的问题。 如何判断测试实际"看到"的内容? 我尝试了另一个堆栈溢出用户建议的不同问题,但在这种情况下,我发现它的用途有限。

任何想法或建议将不胜感激。 提前感谢!

-马 特

你应该先编写测试;)

以您的测试为起点,我一直在努力完成整个过程。 我已经到了和你一样的错误。使用 pry-rails gem 并将 binding.pry 放入测试中:

it { binding.pry ; should have_link('unlock', href: user_path(locked_user)) }

(在搞砸了很多之后)我从测试复制并粘贴到命令提示符:

should have_link('unlock', href: user_path(locked_user))

并得到错误。 将其更改为:

should have_link('unlock', href: user_path(User.first))

工程。 在提示符下输入locked_user向我显示用户记录。接下来我输入了page.body,它显示我的锁定用户甚至没有出现在页面上。 (通过输入User.count确认,发现它是33,所以它在第2页上。您可能没有此问题,具体取决于您的测试对规范的嵌入程度。 我意识到我不小心将其嵌入到另一个规范中。 当我把它移出(User.count == 2)时,它仍然不起作用。 我的locked_user仍然不在页面上。 User.all也没有包括用户。 哈特尔在第10章中提到,

这使用让!(读作"让砰")方法代替让;原因是 let 变量是惰性的,这意味着它们只有在被引用时才会出现。

把让改成让!,它奏效了。 (User.count == 3,包括这次的locked_user。 这是测试块。

describe "as an admin user" do
  let(:admin) { FactoryGirl.create(:admin) }
  before do
    sign_in admin
    visit users_path
  end
...
  describe "other users should have an unlock link" do  ## changed the description
    let!(:locked_user) { FactoryGirl.create(:locked) }
    before { visit users_path }
    it { should have_link('unlock', href: user_path(locked_user)) }
  end
end

我的代码还没有解锁任何东西(我需要另一个测试......),但链接在应该的时候显示出来。 :)

    it { should have_link('unlock', href: user_path(locked_user)) }

乍一看,您需要使用类似的东西 response.body.should have...page.should.have... .

也可能需要render_views

你可能想要:

let!(:locked_user) { FactoryGirl.create(:locked) }

请注意,我使用的是let!()而不是let()。请参阅 rspec 文档,了解有关 let() vs let!() 以及为什么它很重要的更多信息。

最新更新