2010-06-11 17 views
5

Tengo problemas para entender por qué no puedo encontrar este método de controlador :load_user, ya que todas mis pruebas fallan si cambio la implementación real de :load_user para no devolver e instancia de @user.Anulando un before_filter con RSpec

¿Alguien puede ver por qué mi stub (controller.stub!(:load_user).and_return(@user)) parece que no se llama cuando RSpec hace una solicitud al controlador?

require 'spec_helper' 

describe TasksController do 

    before(:each) do 
    @user = Factory(:user) 
    sign_in @user 
    @task = Factory(:task) 
    User.stub_chain(:where, :first).and_return(@user) 
    controller.stub!(:load_user).and_return(@user) 
    end 

    #GET Index 
    describe "GET Index" do 

    before(:each) do 
     @tasks = 7.times{Factory(:task, :user => @user)} 
     @user.stub!(:tasks).and_return(@tasks) 
    end 

    it "should should find all of the tasks owned by a user" do 
     @user.should_receive(:tasks).and_return(@tasks) 
     get :index, :user_id => @user.id 
    end 

    it "should assign all of the user's tasks to the view" do 
     get :index, :user_id => @user.id 
     assigns[:tasks].should be(@tasks)  
    end 
    end 

    #GET New 
    describe "GET New" do 

    before(:each) do 
     @user.stub_chain(:tasks, :new).and_return(@task) 
    end 

    it "should return a new Task" do 
     @user.tasks.should_receive(:new).and_return(@task) 
     get :new, :user_id => @user.id 
    end 
    end 

    #POST Create 
    describe "POST Create" do 

    before(:each) do 
     @user.stub_chain(:tasks, :new).and_return(@task) 
    end 

    it "should create a new task" do 
    @user.tasks.should_receive(:new).and_return(@task) 
     post :create, :user_id => @user.id, :task => @task.to_s 
    end 

    it "saves the task" do 
     @task.should_receive(:save) 
     post :create, :user_id => @user.id, :task => @task 
    end 

    context "when the task is saved successfully" do 

     before(:each) do 
     @task.stub!(:save).and_return(true) 
     end 

     it "should set the flash[:notice] message to 'Task Added Successfully'"do 
     post :create, :user_id => @user.id, :task => @task 
     flash[:notice].should == "Task Added Successfully!" 
     end 

     it "should redirect to the user's task page" do 
     post :create, :user_id => @user.id, :task => @task 
     response.should redirect_to(user_tasks_path(@user.id)) 
     end 
    end 

    context "when the task isn't saved successfully" do 

     before(:each) do 
     @task.stub(:save).and_return(false) 
     end 

     it "should return to the 'Create New Task' page do" do 
     post :create, :user_id => @user.id, :task => @task 
     response.should render_template('new') 
     end 
    end 
    end 

    it "should attempt to authenticate and load the user who owns the tasks" do 

    context "when the tasks belong to the currently logged in user" do 

     it "should set the user instance variable to the currently logged in user" do 
     pending 
     end 

    end 

    context "when the tasks belong to another user" do 

     it "should set the flash[:notice] to 'Sorry but you can't view other people's tasks.'" do 
     pending 
     end 

     it "should redirect to the home page" do 
     pending 
     end 
    end 
    end 
end 

class TasksController < ApplicationController 
    before_filter :load_user 

    def index 
    @tasks = @user.tasks 
    end 

    def new 
    @task = @user.tasks.new 
    end 

    def create 
    @task = @user.tasks.new 
    if @task.save 
     flash[:notice] = "Task Added Successfully!" 
     redirect_to user_tasks_path(@user.id) 
    else 
     render :action => 'new' 
    end 
    end 

    private 

    def load_user 
    if current_user.id == params[:user_id].to_i 
     @user = User.where(:id => params[:user_id]).first 
    else 
     flash[:notice] = "Sorry but you can't view other people's tasks." 
     redirect_to root_path 
    end 
    end 
end 

¿Alguien puede ver por qué mi stub no funciona? Como dije, mis pruebas solo pasan si me aseguro de que load_user funciona, si no, todas mis pruebas fallan, lo que me hace pensar que RSpec no está usando el stub que creé.

+0

Lo siento, no tengo una respuesta real, pero asegúrese de que el controlador que está copiando en sus pruebas y el controlador que realmente ejecuta el código son la misma instancia. Puede verificar su 'object_id' para asegurarse. – x1a4

Respuesta

8

apagando load_user rompe sus pruebas porque apagando el método neutros TI. Cuando el controlador llama al load_user, ya no ejecuta su código original. Ahora solo devuelve lo que especifique en and_return(...) (que se devuelve a la pila de devolución de llamada ActionController, que ignora cualquier cosa que no sea false).

Su código de controlador no está utilizando el valor de retorno de ese método; está usando la variable instanciada dentro de. Dado que el código original para el método load_user no se está ejecutando, la instancia de la variable @user nunca se crea una instancia. (La variable @user en sus pruebas solo es visible para sus pruebas).

Pero con todos los otros stubs que tiene, no veo ningún motivo por el que deba cerrar load_user. Siempre que esté borrando current_user para devolver @user (que supongo que se está haciendo en el método sign_in), entonces no debería haber ninguna necesidad.

+0

Esta es una gran explicación, si pudiera votarla más, lo haría. Muchas gracias, la explicación sobre devolver @user vs instanciando @user realmente me ayudó a hacer clic para mí. – TheDelChop

2

también se puede tratar de verificar que las obras del trozo de hacer una afirmación como

controller.current_user.should == @user