RSPECコントローラテストエラー未定義方法NIL:NILCLASS
-
20-12-2019 - |
質問
私はRSPECに慣れています、そして私はBDDマインドセット全体に参加しようとしているので、このエラーについてはかなり逆らっています。テストしようとしているRailsエンジンがあります。これが掲示コントローラです。基本的に行動の前に私はコースのリストを入力したいです。
class BulletinsController < ApplicationController
before_filter :get_courses
def new
@bulletin = Bulletin.new(author_id: @user.id)
end
...
private
def get_courses
if @user.has_role? :admin
@course_list = Course.all.sort_by(&:start_date)
...
end
end
.
アプリケーションコントローラには、各要求に対して実行したい方法がいくつかあります。私はホストアプリで除画を使用していますので、current_userメソッド
にアクセスできます。class ApplicationController < ::ApplicationController
before_filter :get_user
...
def get_user
@user = current_user
end
...
end
.
そしてここで私が実行しようとしている仕様:
describe BulletinsController do
routes { MyEngine::Engine.routes }
before { controller.stub(:authenticate_user!).and_return true }
before { controller.stub(:get_user).and_return (@user = create(:user)) }
describe "GET #new" do
it "assigns a new bulletin to @bulletin" do
bulletin = create(:bulletin)
controller.stub(:get_courses)
get :new
assigns(:bulletin).should eq(bulletin)
end
end
end
.
仕様を実行しようとすると、エラーが発生します。
NoMethodError: undefined method 'id' for nil:NilClass
.
私はこれを受けていることを理解しています@userは、それがBulletin Buildingで呼ばれたときに定義されていません。ただし、SPECの前のブロックは、GET_USER FILTERをスタブアウトした後に@user変数を定義していると思いました。コンソールの工場をテストするときは、すべてが適切な協会(Bulletin - > Author、Bulletin - >コースなどで作成されているようです。
@user変数が私のコントローラコードに実行されていない理由に関して、不足しているのはわかりません。 RSPECのための洞察や優れたチュートリアルは大いに感謝されます。
解決
current_user
をスタブにする必要があると思います(get_user
をスタブにする必要はありません):
before { controller.stub(:current_user).and_return (@user = create(:user)) }
.
そして私は良い習慣がユーザーにさせることです(あなたがそれを複数回必要な場合):
routes { MyEngine::Engine.routes }
let!(:user) { create(:user) }
before { controller.stub(:current_user).and_return user }
.
プライベートメソッドへのアクセスが必要な場合は、次のようなものを試すことができます。
subject.send(:current_user=, user)
.
は、controller
の代わりにsubject
であり、サポートするバージョンはわかりません。
更新。実際には、プライベートメソッドをテストするのは本当にトリッキーです。current_user
のdevise
が次のように定義されていることを確認しました:
def current_#{mapping}
@current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end
.
だから、warden.authenticate
を返すためにStub user
を試すことができます。
allow_any_instance_of(Warden).to receive(:authenticate).and_return(create(:user))
. 他のヒント
練習する方法を勉強しようとしていることは、どのように考えるのかを理解していない限り、非常に困難になります。
テストする方法は、それらのドキュメントに従って考案テストヘルパーを使用してユーザーにサインインすることです。 https://'github.com/plataformatec/devise### --helpers
describe BulletinsController do
routes { MyEngine::Engine.routes }
before { sign_in(user) }
let!(:user) { create(:user) }
describe "GET #new" do
it "assigns a new bulletin to @bulletin" do
bulletin = create(:bulletin)
controller.stub(:get_courses)
get :new
assigns(:bulletin).should eq(bulletin)
end
end
end
.
このように、あなたはそれを考案し、それをスチブすることを気にする必要はありません。あなた自身の方法のテストに焦点を当てるだけです。:)