如何使用Rspec + Devise + FactoryGirl签入和签出用户进行测试

时间:2017-02-20 11:53:15

标签: ruby-on-rails rspec devise warden

我是Rspec的新手,但我已经成功地设置了一个工作(至少在我的测试中到目前为止)设置,让我可以使用FactoryGirl +测试登录/注销状态中的各种行为设计和守望者助手。该流程遵循以下基本步骤:

  1. Factory girl定义了一般用户
  2. 每个需要登录的测试块都使用before(:each)挂钩在
  3. 中签名用户
  4. rails_helper config在每次测试后使用after:each hook
  5. 删除用户登录

    我已经看了很多代码示例来实现这个功能,但是我还没有找到一个完整的往返行程,虽然我知道这在我的设置中有效,但我想知道它是否正在&#39 ; s是正确的方式,具体来说,我是不是在不必要地复制任何东西(比如用户签署撕裂)或创造未来的意外行为。

    以下是每个步骤的相关代码和样本测试:

    规格/ factories.rb

    FactoryGirl.define do
    
      factory :user do
        sequence(:name)       { |n| "person #{n}"}
        sequence(:email)      { |n| "person#{n}@example.com" }
        password              'foobar'
        password_confirmation 'foobar'
        confirmed_at          Time.now
        sequence(:id)         { |n| n }
      end
    end
    

    规格/ rails_helper.rb

    ...
      # Add login/logout helpers from Devise
      config.include Devise::Test::ControllerHelpers, type: :controller
      config.include Devise::Test::ControllerHelpers, type: :view
    
      # Include Warden test helpers specifically for login/logout
      config.include Warden::Test::Helpers
    
      # Add capybara DSL
      config.include Capybara::DSL
    
      # Tear down signed in user after each test
      config.after :each do
        Warden.test_reset!
      end
    

    spec / views / static_pages(样本测试)

    RSpec.describe 'static_pages home, signed in', type: :view do
      before(:each) do
        @user = build(:user)
        login_as(@user)
      end
    
      it 'should display the correct links when signed in' do
    
        visit root_path
    
        # links which persist in both states
        expect(page).to have_link('Site Title', href: root_path, count: 1)
    
        # links which drop out after login
        expect(page).not_to have_link('Login', href: new_user_session_path)
        expect(page).not_to have_link('Join', href: signup_path)
    
        # links which are added after login
        expect(page).to have_link('Add Item', href: new_item_path)
        expect(page).to have_link('My Items', href: myitems_path)
      end
    end
    

1 个答案:

答案 0 :(得分:2)

您的设置完全正常。正如@Greg Tarsa所说的那样,您可能希望在功能级别执行此类测试。我的另一件事是,应该使用一个单一的规格来测试一件事,例如它应该是expect块中的单个(或几个)it。但它并不是严格的规则 - 由你决定。

我使用以前的提示和功能样式语法对您的设置进行了一些重构。也许它会很有用:

  background do
    @user = build(:user)
    login_as(@user)
    visit root_path
  end

  scenario "links persist in both states" do
    expect(page).to have_link('Site Title', href: root_path, count: 1)
  end

  scenario "links dropped out after login" do
    expect(page).not_to have_link('Login', href: new_user_session_path)
    expect(page).not_to have_link('Join', href: signup_path)
  end

  scenario "links added after login" do
    expect(page).to have_link('Add Item', href: new_item_path)
    expect(page).to have_link('My Items', href: myitems_path)
  end