简体   繁体   中英

How to factor Capybara rspec testing code?

I need to test a system in which everything is available only after a user is signed in using Devise. Every time I use "it" I have to include the signup code.

Is there a way to factor the code below so that the "let's me make a new post" test and similar tests won't have to include the sign up?

describe "new post process" do
  before :all do
    @user = FactoryGirl.create(:user)
    @post = FactoryGirl.create(:post)
  end

  it "signs me in" do
    visit '/users/sign_in'
    within(".new_user") do
      fill_in 'Email', :with => 'user@example.com'
      fill_in 'Password', :with => 'password'
    end
    click_button 'Log in'
    expect(page).to have_content 'Signed in successfully'
  end

  it "let's me make a new post" do
    visit '/users/sign_in'
    within(".new_user") do
      fill_in 'Email', :with => 'user@example.com'
      fill_in 'Password', :with => 'password'
    end
    click_button 'Log in'

    visit '/posts/new'
    expect( find(:css, 'select#post_id').value ).to eq('1')
  end

end

Your first option is to use the Warden methods provided, as per the documentation on this page:

https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara

Your second option is just to login for real in your tests as you have done in your examples. You can streamline this though by creating some helper methods to do the login work rather than duplicating the code in all of your tests.

To do this, I would create a support directory within your spec directory, and then a macros directory within that. Then create a file spec/support/macros/authentication_macros.rb :

module AuthenticationMacros
  def login_as(user)
    visit '/users/sign_in'
    within('.new_user') do
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
    end
    click_button 'Log in'
  end
end

Next, update your RSpec config to load your macros. In either spec_helper.rb or rails_helper.rb if you're using a newer setup:

# Load your support files
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

# Include the functions defined in your modules so RSpec can access them
RSpec.configure do |config|
  config.include(AuthenticationMacros)
end

Finally, update your tests to use your login_as function:

describe "new post process" do
  before :each do
    @user = FactoryGirl.create(:user)
    @post = FactoryGirl.create(:post)

    login_as @user
  end

  it "signs me in" do
    expect(page).to have_content 'Signed in successfully'
  end

  it "let's me make a new post" do
    expect( find(:css, 'select#post_id').value ).to eq('1')
  end
end

Obviously, make sure you have password defined in your user factory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM