Pregunta

Soy nuevo en el Rspec y estoy tratando de conseguir en el conjunto de la BDD mentalidad, así que estoy bastante perplejo acerca de este error.Me han rieles motor que estoy tratando de probar.Aquí está el boletín de controlador.Básicamente, antes de cualquier acción que desea rellenar la lista de cursos.

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

El controlador de aplicación tiene algunos métodos que quiero que se ejecute en cada solicitud.Yo estoy usando el de idear en la aplicación host para tener acceso a la current_user método

class ApplicationController < ::ApplicationController
  before_filter :get_user
  ...
  def get_user
    @user = current_user
  end
  ...
end

Y aquí está la especificación estoy tratando de ejecutar:

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

Cuando intento ejecutar la especificación, me sale el error:

NoMethodError: undefined method 'id' for nil:NilClass

Yo entiendo que yo estoy haciendo esto porque @usuario no está definido cuando es llamado en el boletín de la construcción;sin embargo, pensé que antes de bloque en la especificación se define la @variable de usuario después de golpear el :get_user filtro.Cuando hago la prueba de las fábricas en la consola, todo parece estar creado con las asociaciones adecuadas (boletín -> autor, boletín -> curso, etc).

No estoy seguro de lo que me estoy perdiendo de por qué el @variable de usuario no está siendo llevado a través de mi controlador de código.Conocimientos y/o buenos tutoriales para rspec sería muy apreciada.

¿Fue útil?

Solución

Supongo que Usted también necesita a punta de current_user y va a ser suficiente (no hay necesidad de punta de get_user):

before { controller.stub(:current_user).and_return (@user = create(:user)) }

Y supongo que la buena práctica es permitir al usuario (si necesita más de una vez):

routes { MyEngine::Engine.routes }
let!(:user) { create(:user) }
before { controller.stub(:current_user).and_return user }

Si usted necesita un acceso a métodos privados, usted puede intentar algo como esto:

subject.send(:current_user=, user)

Podría ser un controller en lugar de subject, no está seguro de qué versión que soporta.

La actualización.En realidad, es muy complicado probar métodos privados.He comprobado que current_user en devise se define como:

def current_#{mapping}
  @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end

Así, se puede intentar punta de warden.authenticate para las devoluciones user:

allow_any_instance_of(Warden).to receive(:authenticate).and_return(create(:user))

Otros consejos

Tratando de resumir los métodos que el diseño podría estar usando será bastante difícil a menos que entienda cómo funciona los dispositivos.

La forma recomendada de probar es simplemente iniciar sesión en el usuario utilizando el ayudante de prueba de diseño según su documentación: https://github.com/plataformatec/devise#test-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

De esta manera, no tendrá que preocuparse por diseñar métodos y derribarlo.Simplemente concéntrese en probar su propio método.:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top