Rspec, должен быть лучший способ написать это - PullRequest
0 голосов
/ 25 августа 2011

в моей системе есть 4 класса пользователей: не вошедший в систему, потребитель, производитель и администратор.

В настоящее время я использую Cancan для ACL.

Во время написания rspec я вижу следующее:

describe DealsController do 

  describe "non-signed-in users" do
    before(:each) do 
      @deal = Factory(:deal)
    end

    describe "should be able to" do 
      it "access index" do get :index end
      it "show deal" do get :show, :id => @deal end

      after(:each) do
        response.should be_success
      end
    end

    describe "should not be able to" do 
      it "redeem" do get :redeem end
      it "new" do get :new end
      it "edit" do get :edit, :id => @deal end
      it "update" do get :update, :id => @deal end
      it "destroy" do get :destroy, :id => @deal end

      after(:each) do
        response.should_not be_success
        response.should redirect_to(root_path)
        flash[:error].should == "Permission denied."
      end
    end
  end

  describe "consumers" do 
    before(:each) do 
      @user = test_sign_in(Factory(:user, :role => "consumer"))
      @deal = Factory(:deal)
    end

    describe "should be able to" do 
      it "access index" do get :index end
      it "show deal" do get :show, :id => @deal end

      after(:each) do
        response.should be_success
      end
    end

    describe "should not be able to" do 
      it "redeem" do get :redeem end
      it "new" do get :new end
      ...


      after(:each) do
        response.should_not be_success
        response.should redirect_to(root_path)
        flash[:error].should == "Permission denied."
      end
    end
 end

  describe "producer" do 
    before(:each) do 
      @user = test_sign_in(Factory(:user, :role => "producer"))
      @business = Factory(:business, :user_id => @user.id)
      @deal = Factory(:deal, :business_id => @business.id)
    end

    it "should be able to access index" do 
      get :index
      response.should be_success
    end

    describe "in show deals" do 
      it "should be able to see merchant controls for his deal" do 
        get :show, :id => @deal
        response.should have_selector('h3', :content => "Merchant Controls")
      end

      it "should not be able to see merchant controls for other's deal" do 
        @user2 = Factory(:user, :role => "producer")
        @business2 = Factory(:business, :user_id => @user2.id)
        @deal2 = Factory(:deal, :business_id => @business2.id)
        get :show, :id => @deal2

        response.should_not have_selector('h3', :content => "Merchant Controls")
      end
    end

    describe "should not be able to" do 
      it "new" do get :new end
      ...

      after(:each) do
        response.should_not be_success
        response.should redirect_to(root_path)
        flash[:error].should == "Permission denied."
      end
    end
 end

end

Я даже не заполнил раздел администратора, но я уверен, что это не рекомендуемый путьделая это.

Какой способ лучше?

Ответы [ 2 ]

4 голосов
/ 27 августа 2011

Вы должны рассмотреть вопрос о принятии нового стиля для однострочников.Например, сделайте что-то вроде этого

describe "should be able to" do
  it "access index" { get :index }
  it "show deal"    { get :show, :id => @deal }
  after(:each)      { response.should be_success }
end

Также вы можете подумать о создании настраиваемого сопоставителя для повторяющихся многострочных ожиданий.Например, следующее:

after(:each) do
  response.should_not be_success
  response.should redirect_to(root_path)
  flash[:error].should == flash
end

можно заменить на

after(:each) { response.should fail_redirect_and_flash(root_path, 'Permission denied.') }

, используя следующий пользовательский код сопоставления

RSpec::Matchers.define :fail_redirect_and_flash do |path,flash|
  match do |response|
    response.should_not be_success
    response.should redirect_to(path)
    flash[:error].should == flash
  end
end

Кроме того, многие люди даже нене стоит писать модульные тесты контроллеров, потому что в хорошо спроектированных контроллерах, как правило, очень мало кода (они обычно просто устанавливают некоторые переменные, используя методы в модели, и выполняют рендеринг / перенаправление, следовательно, большая часть тестирования фактически происходит в моделях).Вместо этого они обертывают оба контроллера и рассматривают тесты вместе и используют огурец.Вы по-прежнему сталкиваетесь с таким же уродливым беспорядком кода, но некоторые люди находят, что им легче управлять.

На этой заметке вы увидите, что ваша спецификация "не должна видеть элементы управления торговцами для других сделок."на самом деле проверяет ваш взгляд, а не столько ваш контроллер.Вам, вероятно, следует извлечь любую логику, которую вы используете в своем контроллере, чтобы показать элементы управления торговцами, вставить ее в помощника и протестировать в изоляции.Это поможет сохранить ваши контроллеры тонкими.Например, у вас может быть следующий помощник, который вы используете в своих представлениях

def merchant_controls(deal, business)
  if business.can? :update, deal
    # render html
  end
end

И у вас может быть спецификация только для этого вспомогательного метода ...

Describe "merchant_controls(deal, business)" do
  before(:all) do
    @business_a = create(:business)
    @deal_a = create(:deal, :business_id => @business_a)
    @business_b = create(:business)
    @deal_b = create(:deal, :business_id => @business_b)
  end

  it "a business should see merchant controls next to its own deals" do
    merchant_controls(@business_a, @deal_a).should eq("blahblah")
  end
  it "a business should not see merchant controls next to other business' deals" do
    merchant_controls(@business_a, @deal_b).should eq("")
  end
end

Надеюсь, это поможет.

0 голосов
/ 25 августа 2011

Честно говоря, если вы заботитесь о приложении, особенно если оно связано с взаимодействием с пользователем, то проведение тонны приемочных тестов более чем нормально. Очевидно, не увлекайтесь и начинайте тестировать такие вещи, как видимые цвета или что-то в этом роде. Но если вы не проводите тщательное тестирование, вы не являетесь программистом, которым могли бы быть.

Возможно, вы захотите разбить свои тесты на более управляемые тесты. Возможно сделать отдельный физический файл для каждого из четырех типов пользователей. Я не могу вспомнить, но я не думаю, что это вызывает какие-либо проблемы с RSpec.

Лично я думаю, что использование RSpec для приемочных испытаний слишком ужасно. Слишком песчаный. Я предпочитаю с большим отрывом использовать огурец (http://www.cukes.info). Это значительно упрощает приемочные тесты, особенно если вы также хотите протестировать javascript. По моему мнению, они быстрее пишутся и чище. это немного, если бы я был тобой, чтобы увидеть, если это подходит для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...