2010-06-11 6 views
5

Tôi không hiểu tại sao tôi không thể khai báo phương pháp điều khiển này :load_user, vì tất cả các thử nghiệm của tôi đều thất bại nếu tôi thay đổi thực hiện thực tế :load_user để không trả lại và thể hiện @user.Viết một front_filter với RSpec

Ai có thể thấy lý do tại sao cuống của tôi (controller.stub!(:load_user).and_return(@user)) có vẻ không thực sự được gọi khi RSpec đưa ra yêu cầu cho bộ điều khiển?

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 

Ai có thể xem lý do tại sao bài của tôi không hoạt động? Như tôi đã nói, các bài kiểm tra của tôi chỉ vượt qua nếu tôi đảm bảo rằng load_user hoạt động, nếu không, tất cả các thử nghiệm của tôi đều thất bại, điều này khiến tôi nghĩ rằng RSpec không sử dụng cuống mà tôi đã tạo.

+0

Xin lỗi tôi không có câu trả lời thực sự, nhưng hãy chắc chắn rằng bộ điều khiển bạn đang stubbing trong các thử nghiệm của bạn và bộ điều khiển thực sự thực thi mã là cùng một ví dụ. Bạn có thể kiểm tra 'object_id' của họ để chắc chắn. – x1a4

Trả lời

8

loại bỏ dần từng load_user phá vỡ các xét nghiệm của bạn bởi vì stubbing các neuters phương pháp đó. Khi trình điều khiển gọi số load_user, trình điều khiển không còn chạy mã ban đầu của bạn nữa. Hiện tại, bạn chỉ cần trả lại bất kỳ điều gì bạn chỉ định trong and_return(...) (đang được trả về ngăn xếp gọi lại ActionController, bỏ qua bất kỳ thứ gì khác ngoài false).

Mã điều khiển của bạn không sử dụng giá trị trả lại của phương thức đó; nó đang sử dụng biến được tạo ra ngay lập tức trong phạm vi nó. Vì mã ban đầu cho phương thức load_user không được chạy, biến cá thể @user không bao giờ được khởi tạo. (Biến số @user trong các bài kiểm tra của bạn chỉ hiển thị với các bài kiểm tra của bạn.)

Nhưng với tất cả các cuống khác bạn có, tôi không thấy bất kỳ lý do nào bạn cần phải loại bỏ load_user. Miễn là bạn đang stubbing current_user để trả lại @user (mà tôi giả định đang được thực hiện theo phương pháp sign_in), thì không cần bất kỳ nhu cầu nào.

+0

Đây là một lời giải thích tuyệt vời, nếu tôi có thể bỏ phiếu nhiều hơn tôi sẽ làm. Cảm ơn bạn rất nhiều, lời giải thích về việc trở về @user vs instantiating @user thực sự đã giúp tôi nhấp vào. – TheDelChop

2

bạn cũng có thể thử để xác minh rằng các công trình còn sơ khai bằng cách thực hiện một sự khẳng định như

controller.current_user.should == @user