2012-05-10 16 views
20

Estoy tratando de colgar un método en un asistente que está definido en mi controlador. Por ejemplo:No se puede colgar el método auxiliar 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 

En mi 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 

En 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 

le pregunté a una pregunta similar here, pero se establecieron en un trabajo alrededor. Este extraño comportamiento se ha incrementado nuevamente y me gustaría entender por qué esto no funciona.

ACTUALIZACIÓN: He encontrado que llamar antes controller.stub!(:current_user).and_return(@user)helper.stub!(...) es lo que está causando este comportamiento. Esto es bastante fácil de arreglar en spec/support/authentication.rb, pero ¿esto es un error en Rspec? No veo por qué se espera que no sea capaz de cortar un método en un helper si ya se ha conectado en un controlador.

+0

Trate apagando el método a través ApplicationController, ya que es donde se define. 'ApplicationController.stub (: current_user => @user)' EDITAR: Ahora estoy pensando que podría no funcionar. – dwhalen

+0

No, no funcionó. Intenté 'any_instance' también sin suerte. De hecho lo he hecho funcionar, pero estoy un poco confundido (puede haber encontrado un error con rspec). Actualizaré la pregunta en breve. – Brad

+0

Suena como un error. Definitivamente vale la pena archivar un problema en https://github.com/rspec/rspec-mocks/issues (y probar con la última versión). –

Respuesta

8

probar esto, que trabajó para mí:

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 primera parte se basa en this reply por el autor de RSpec, y la segunda parte se basa en this Stack Overflow answer.

+0

... y luego las pruebas realmente necesitan probar @helper, no SomeHelper. – LisaD

+0

no funciona – Jerry

20

Actualizar a la respuesta de Matthew Ratzloff: ¡No necesita el objeto de instancia y el talón! ha quedado en desuso

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

Editar. La forma RSpec 3 a stub! sería:

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

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

+2

no funciona. – Chamnap

+0

He solucionado mi respuesta para 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

En RSpec 3,5 RSpec, parece que helper ya no es accesible desde un it bloquear. (Se le dará el siguiente mensaje:

helper no está disponible desde el interior de un ejemplo (por ejemplo, un bloque de it) o a partir de construcciones que se ejecutan en el alcance de un ejemplo (por ejemplo before, let, etc) de ella. sólo está disponible en un grupo de ejemplo (por ejemplo, un bloque describe o context).

(me parece que no puede encontrar ninguna documentación sobre este cambio, esto es todo el conocimiento obtenido de forma experimental).

La clave para resolver este es saber que los métodos de ayuda son los métodos de instancia, y que para sus propios métodos de ayuda que es fácil de hacer esto:

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

Esto es lo que finalmente funcionó para mí

Notas al pie/crédito a quien Debido:

0

Esto funcionó para mí en el caso de 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 
Cuestiones relacionadas