コントローラで定義されているヘルパーのメソッドをスタブしようとしています。例えば:
_class ApplicationController < ActionController::Base
def current_user
@current_user ||= authenticated_user_method
end
helper_method :current_user
end
module SomeHelper
def do_something
current_user.call_a_method
end
end
_
私のRspecでは:
_describe SomeHelper
it "why cant i stub a helper method?!" do
helper.stub!(:current_user).and_return(@user)
helper.respond_to?(:current_user).should be_true # Fails
helper.do_something # Fails 'no method current_user'
end
end
_
_spec/support/authentication.rb
_で
_module RspecAuthentication
def sign_in(user)
controller.stub!(:current_user).and_return(user)
controller.stub!(:authenticate!).and_return(true)
helper.stub(:current_user).and_return(user) if respond_to?(:helper)
end
end
RSpec.configure do |config|
config.include RspecAuthentication, :type => :controller
config.include RspecAuthentication, :type => :view
config.include RspecAuthentication, :type => :helper
end
_
私は同様の質問をしました ここ 、しかし回避策に落ち着きました。この奇妙な振る舞いが再び忍び寄り、なぜこれが機能しないのかを理解したいと思います。
[〜#〜] update [〜#〜]:controller.stub!(:current_user).and_return(@user)
の前にhelper.stub!(...)
を呼び出すことがわかりましたこの動作を引き起こしているのはです。これは_spec/support/authentication.rb
_で修正するのに十分簡単ですが、これはRspecのバグですか?メソッドがすでにコントローラーでスタブされている場合、ヘルパーでメソッドをスタブできないと予想される理由がわかりません。
これを試してください、それは私のために働きました:
describe SomeHelper
before :each do
@helper = Object.new.extend SomeHelper
end
it "why cant i stub a helper method?!" do
@helper.stub!(:current_user).and_return(@user)
# ...
end
end
最初の部分はRSpecの作者による この返信 に基づいており、2番目の部分は このスタックオーバーフローの回答 に基づいています。
Matthew Ratzloffの回答を更新します。インスタンスオブジェクトとスタブは必要ありません!非推奨になりました
_it "why can't I stub a helper method?!" do
helper.stub(:current_user) { user }
expect(helper.do_something).to eq 'something'
end
_
編集します。 _stub!
_へのRSpec3の方法は次のようになります:
allow(helper).to receive(:current_user) { user }
RSpec 3.5 RSpecでは、helper
ブロックからit
にアクセスできなくなったようです。 (次のメッセージが表示されます:
helper
は、例内(例:it
ブロック)または例のスコープ内で実行される構造(例:before
、let
)からは使用できません。 、など)。サンプルグループ(例:describe
またはcontext
ブロック)でのみ使用できます。
(この変更に関するドキュメントが見つからないようです。これはすべて実験的に得られた知識です)。
これを解決するための鍵は、ヘルパーメソッドがインスタンスメソッドであり、独自のヘルパーメソッドの場合はこれを簡単に実行できることを知っていることです。
allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user)
これが最終的に私のために働いたものです
脚注/クレジットクレジットの期限:
これはRSpec3の場合に私のために働いた:
let(:user) { create :user }
helper do
def current_user; end
end
before do
allow(helper).to receive(:current_user).and_return user
end
Rspec 3
user = double(image: urlurl)
allow(helper).to receive(:current_user).and_return(user)
expect(helper.get_user_header).to eq("/uploads/user/1/logo.png")