Search code examples
ruby-on-railsrubyruby-on-rails-4factory-botrspec3

DRYing up Rspec test


I'm at the point where I'm developing an admin dashboard part of my app, and for every action the user needs to be logged in.

So for example this test :

describe 'GET #index' do
    let(:user) { create(:user) }

    before do
      sign_in user
    end

    it 'responds successfully with an HTTP 200 status code' do
      get :index
      expect(response).to be_success
      expect(response).to have_http_status(200)
    end

    it 'renders the index template' do
      get :index
      expect(response).to render_template('index')
    end

    it 'loads all of the tags into @tags' do
      tag1 = create(:tag)
      tag2 = create(:tag)
      get :index

      expect(assigns(:tags)).to match_array([tag1, tag2])
    end
  end

Is working just fine, but I was thinking if I could extract the user creation and sign_in part to something that I can use for all these admin tests. I tried this :

describe 'GET #index', admin: true do
 ....all the same as above, except user creation and before sign in block
end

Then in my spec/spec_helper.rb I added the following :

config.before(:each, admin: true) do |_example|
  before do
    sign_in FactoryGirl.create(:user)
  end
end

Unfortunately this didn't work, is there a better way that I can do this? accomplish the same thing, that I can put the login code in one place and not have to re-past it in my admin tests.

I'm using Rails 4 and Rspec 3.


Solution

  • you have an extra before block. remove it so this ...

    config.before(:each, admin: true) do |_example|
      before do
        sign_in FactoryGirl.create(:user)
      end
    end
    

    becomes this ...

    config.before(:each, admin: true) do
      sign_in FactoryGirl.create(:user)
    end
    

    Also, if these are controller specs (as they appear to be) then this ...

    describe 'GET #index' do
    

    should actually look like this ...

    describe SomeController, type: :controller, admin: true do