Динамически генерировать общие примеры в RSpec 2? - PullRequest
9 голосов
/ 27 мая 2011

Я пытаюсь сохранить свои спецификации СУХИМ, создавая общую группу примеров, которая выполняет стандартные проверки всех контроллеров администратора (всех контроллеров в пространстве имен Admin моего проекта). Я изо всех сил пытаюсь выяснить, как это сделать, поскольку общий пример должен содержать информацию о том, какие действия и параметры использовать. В идеале он должен содержать значимые ошибки, если тест не пройден (т. Е. Включать детали действия, которое он тестировал).

require 'spec_helper'

shared_examples "an admin controller" do

  before(:each) do
    @non_admin = User.make
    @admin = User.make(:admin)
  end

  context "as an admin user" do
    @actions.each do |action, params|

      specify "I should be able to access ##{action.last} via #{action.first}" do
        self.active_user = @admin
        send(action.first, action.last, params)

        response.status.should be_ok
      end

    end   
  end

  context "as a regular user" do
    @actions.each do |action, params|

      specify "I should be denied access to ##{action.last}" do
        self.active_user = @non_admin
        send(action.first, action.last, params)

        response.status.should be 403
      end

    end   
  end

end

describe Admin::UserNotesController do

  @user = User.make
  @actions = { [:get, :index]   => { :user_id => @user.id },
               [:get, :new]     => { :user_id => @user.id },
               [:post, :create] => { :user_id => @user.id } }

  it_behaves_like "an admin controller"

end

Эта ошибка по очевидной причине, что @actions не видна группе общих примеров. Если я использую let, это доступно только в контексте примера, а не в контексте блока describe. Есть идеи?

1 Ответ

27 голосов
/ 27 мая 2011

Вот намного более чистый способ, который должен работать:

require 'spec_helper'

shared_examples "an admin controller" do |actions|
  context "as an admin user" do
    actions.each_pair do |action, verb|
      specify "I should be able to access ##{action} via #{verb}" do
        send(verb, action, :user_id => User.make(:admin).id)
        response.status.should be_ok
      end
    end   
  end

  context "as a regular user" do
    actions.each_pair do |action, verb|
      specify "I should be denied access to ##{action}" do
        send(verb, action, :user_id => User.make.id)
        response.status.should be 403
      end
    end   
  end
end

describe Admin::UserNotesController do
  it_behaves_like "an admin controller", { 
    :index  => :get,
    :new    => :get,
    :create => :post
  }
end

См. http://relishapp.com/rspec/rspec-core/v/2-6/dir/example-groups/shared-examples для получения дополнительной информации

...