2012-05-10 11 views
20

Sto provando a eseguire lo stub di un metodo su un helper definito nel mio controller. Per esempio:Impossibile eseguire il metodo di supporto stub con rspec

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 

Nel mio 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 

In 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 

ho fatto una domanda simile here, ma optato per un lavoro in giro. Questo strano comportamento è di nuovo insinuato e mi piacerebbe capire perché non funziona.

UPDATE: ho trovato che chiamare controller.stub!(:current_user).and_return(@user) prima helper.stub!(...) è ciò che sta causando questo comportamento. Questo è abbastanza facile da risolvere in spec/support/authentication.rb, ma si tratta di un bug in Rspec? Non vedo perché ci si aspetterebbe che non sia in grado di stubare un metodo su un helper se fosse già stato stubato su un controller.

+0

Prova spegnendo il metodo attraverso l'ApplicationController, dal momento che è in cui è definito. 'ApplicationController.stub (: current_user => @user) EDIT: Ora sto pensando che potrebbe non funzionare. – dwhalen

+0

No, non ha funzionato. Ho provato anche "any_instance" senza fortuna. In realtà ho funzionato, ma sono un po 'confuso (potrebbe aver trovato un bug con rspec). Aggiornerò la domanda a breve – Brad

+0

Sembra un bug. Vale sicuramente la pena presentare un problema su https://github.com/rspec/rspec-mocks/issues (e provare con l'ultima versione). –

risposta

8

Prova questa, ha funzionato per me:

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 

La prima parte si basa sulla this reply dall'autore di RSpec, e la seconda parte si basa su this Stack Overflow answer.

+0

... e quindi i test devono effettivamente testare @helper, non SomeHelper. – LisaD

+0

non funziona – Jerry

20

Aggiornamento alla risposta di Matthew Ratzloff: Non è necessario l'oggetto istanza e lo stub! è stato deprecato

it "why can't I stub a helper method?!" do 
    helper.stub(:current_user) { user } 
    expect(helper.do_something).to eq 'something' 
end 

Modifica. Il modo RSpec 3 a stub! sarebbe:

allow(helper).to receive(:current_user) { user }

See: https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/

+2

non funziona. – Chamnap

+0

Ho risolto la mia risposta per RSpec 3. –

2

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") 
1

In RSpec 3.5 RSpec, sembra che helper non è più accessibile da un it bloccare. (Vi darà il seguente messaggio:

helper non è disponibile dall'interno di un esempio (ad esempio un it blocco) o da costrutti che vengono eseguiti nell'ambito di un esempio (ad esempio before, let, ecc) E. è disponibile soltanto su un gruppo di esempio (ad esempio un blocco o describecontext).

(io non riesco a trovare alcuna documentazione su questo cambiamento, questo è tutto conoscenze acquisite sperimentalmente).

La chiave per risolvere questo è sapere che metodi di supporto sono metodi di istanza, e che per i propri metodi di supporto è facile da fare questo:

allow_any_instance_of(SomeHelper).to receive(:current_user).and_return(user) 

Questo è quello che finalmente ha funzionato per me

Note/Onore al merito Due:

0

questo ha funzionato per me nel caso di RSpec 3:

let(:user) { create :user } 
helper do 
    def current_user; end 
end 
before do 
    allow(helper).to receive(:current_user).and_return user 
end 
Problemi correlati