DRYing up Rspec 测试

DRYing up Rspec 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

工作正常,但我在想是否可以将用户创建和 sign_in 部分提取到我可以用于所有这些管理测试的东西中。我试过了:

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

然后在我的 spec/spec_helper.rb 中添加了以下内容:

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

不幸的是,这没有用,有没有更好的方法可以做到这一点?完成同样的事情,我可以将登录代码放在一个地方,而不必在我的管理测试中重新粘贴它。

我正在使用 Rails 4 和 Rspec 3。

共享示例是清理规范和删除代码重复的好方法,请查看 https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples

你有一个额外的前块。删除它,这样...

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

变成这个...

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

此外,如果这些是控制器规格(看起来是这样),那么这...

describe 'GET #index' do

实际上应该是这样的...

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