質問

私は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_userdeviseが次のように定義されていることを確認しました:

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
.

このように、あなたはそれを考案し、それをスチブすることを気にする必要はありません。あなた自身の方法のテストに焦点を当てるだけです。:)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top