8

これは、ログインしていないユーザー (別名ゲスト) が にアクセスしようとしbefore_filterたときにログイン ページにリダイレクトする、非常に典型的なコントローラーの仕様です。/projects/new

describe ProjectsController do
  (...)

  describe "GET new" do
    context 'when not logged in' do
      before { sign_in_nobody }

      context 'creating project' do
        before { get :new }

        it 'denies access' do
          expect(response).to be_redirect
        end
      end
    end
  end
end

私は、ゲストユーザー管理者、および:indexスーパー:show管理にアクセスすることで考えられるすべての結果を特定しました。ログインユーザーでもゲストユーザーでも、管理者であろうとなかろうと、問題はありませんでしたが、実際には、この仕様がDeviseのアクションに触れたのはこれが初めてであり、それは惨めに失敗します.:newbefore_filter :autheticate_user!

expect(response).to be_redirectすでにお気づきかもしれませんが、仕様は にも達していません。

Failures:

1) ProjectsController GET new when not logged in creating project denies access
   Failure/Error: get :new
   ArgumentError:
     uncaught throw :warden
   # ./spec/controllers/projects_controller_spec.rb:344:in `block (5 levels) in <top (required)>'

「rspecとdeviseを使用して認証されていない(ゲスト)ユーザーを適切にテストする方法」という質問への回答を探しましたが、RSpecを使用するためにデバイスに実際にユーザーをログインさせることに問題があることについて誰もが話しているだけです。私がこのように解決した問題:

#spec/support/devise_authenticators.rb
include Devise::TestHelpers

def sign_in_nobody
  @request.env["devise.mapping"] = Devise.mappings[:user]
  sign_in User.new
end

def sign_in_user
  @request.env["devise.mapping"] = Devise.mappings[:user]
  sign_in FactoryGirl.create(:user)
end

ただし、ここで失敗するのはログインではなく、「ログに記録されていない」ことです。これまでのところ、私はまったく何も得ていませんが、人々が何らかの方法でこれらのシナリオをテストする必要があることを知っています.

現在、私はウォークアラウンドを使用しています:

before { sign_in_nobody }

context 'creating project' do
  it 'denies access' do
    expect{ get :new }.to raise_exception("uncaught throw :warden")
  end
end

しかし、実際には正しい(失敗しuncaught throw :wardenた場合にのみ発生するauthenticate_user!ため、期待どおりに使用できます)にもかかわらず、理論的には本当に汚いと感じます。

適切に行う方法はありますか?

before_filter authenticate_user!(... Devise の責任が私のものではないことを考えると、これをまったくテストするべきではないのではないでしょうか?)

4

3 に答える 3

1

つまり、教訓は失敗したuncaught throw :wardenときに起こるということです。authenticate_user!

ユーザーの認証が失敗する理由を突き止めれば、問題は解決します。

于 2016-02-23T13:14:35.343 に答える