6

RSpec で承認をテストする場所はどこですか?

RSpec で Rails アプリケーションを作成する場合、適切と思われる 3 つのフォルダーがあります。

  • スペック/ルーティング
  • 仕様・要望
  • 仕様/コントローラー

ユーザーがログインしているかどうかをテストする必要があるのはどれですか? 複数の仕様タイプでテストする必要がありますか?

4

1 に答える 1

10

あなたの質問には微妙な違いがあります。Authorization通常、ユーザーがアプリ内で持つ権限を参照します。Authenticationサインアップおよびログインしているユーザーへのリファラー。

行く限りAuthentication、私は通常integration/requestsspec またはを使用することを好みacceptance/feature specsます。Capybara DSL (pageおよびvisit) は機能仕様でしか利用できないため、最近では機能仕様が好まれています。2.x アップグレードまでは、リクエスト仕様で許可されていました。

サインアップ、サインイン、サインアウトなどをテストします。例えば、

# signing_up_spec.rb

feature 'Signing up' do
  scenario 'Successful sign up' do
    visit '/'
    within 'nav' do
      click_link 'Sign up'
    end
    fill_in "Email", :with => "user@ticketee.com"
    fill_in "Password", :with => "password"
    fill_in "Password confirmation", :with => "password"
    click_button "Sign up"
    page.should have_content("Please open the link to activate your account.")
  end
end

これにより、より高いレベルの側面をテストし、アプリ内のさまざまなコンポーネント (コントローラー、ビューなど) が連携して動作することを確認できます。これは定義上、統合/受け入れテストです。signing_in_spec.rbとについて上記と同じことをしますsigning_out_spec.rb

Authorizationでは、コントローラの仕様を使用することを選択します。これにより、ユーザーがアクセス権を持つ個々のアクションをテストできます。これらのコントローラーの仕様は、本質的により詳細であり、定義上、単体/機能テストです。たとえば、チケット リソースがあり、特定のユーザーだけが特定の機能にアクセスできることをテストしたいとします。

# tickets_controller_spec.rb

describe TicketsController do
  let(:user) { FactoryGirl.create(:confirmed_user) }
  let(:project) { FactoryGirl.create(:project) }
  let(:ticket) { FactoryGirl.create(:ticket, :project => project,
                                  :user => user) }

  context "standard users" do
    it "cannot access a ticket for a project" do
      sign_in(:user, user)
      get :show, :id => ticket.id, :project_id => project.id
      response.should redirect_to(root_path)
      flash[:alert].should eql("The project you were looking for could not be found.")
    end

    context "with permission to view the project" do
      before do
        sign_in(:user, user)
        define_permission!(user, "view", project)
      end

      def cannot_create_tickets!
        response.should redirect_to(project)
        flash[:alert].should eql("You cannot create tickets on this project.")
      end

      def cannot_update_tickets!
        response.should redirect_to(project)
        flash[:alert].should eql("You cannot edit tickets on this project.")
      end

      it "cannot begin to create a ticket" do
        get :new, :project_id => project.id
        cannot_create_tickets!
      end

      it "cannot create a ticket without permission" do
        post :create, :project_id => project.id
        cannot_create_tickets!
      end

      it "cannot edit a ticket without permission" do
        get :edit, { :project_id => project.id, :id => ticket.id }
        cannot_update_tickets!
      end

      it "cannot update a ticket without permission" do
        put :update, { :project_id => project.id,
                       :id => ticket.id,
                       :ticket => {}
                     }
        cannot_update_tickets!
      end

      it "cannot delete a ticket without permission" do
        delete :destroy, { :project_id => project.id, :id => ticket.id }
        response.should redirect_to(project)
        flash[:alert].should eql("You cannot delete tickets from this project.")
      end

      it "can create tickets, but not tag them" do
        Permission.create(:user => user, :thing => project, :action => "create tickets")
        post :create, :ticket => { :title => "New ticket!",
                                   :description => "Brand spankin' new",
                                   :tag_names => "these are tags"
                                 },
                      :project_id => project.id
        Ticket.last.tags.should be_empty
      end
    end
  end
end

との組み合わせはrspec-rails、Rails アプリ内の両方のタイプのテストでうまく機能することがわかりました。capybarafactory_girl_rails

上記の例は、github の Rails3Book リポジトリから取得したものです。その他の例については、リポジトリをご覧ください。これは、Rails アプリをテストする際の可能性を確認するのに最適な方法です。

于 2013-06-19T22:33:48.150 に答える