Я испытываю затруднения при понимании, почему я, может казаться, не блокирую этот метод контроллера :load_user
, так как все мои тесты перестали работать, если я изменяю фактическую реализацию :load_user
не возвратить и инстанцировать @user
.
Может кто-либо видеть почему мой тупик (controller.stub!(:load_user).and_return(@user)
) кажется, не удается на самом деле быть названным, когда RSpec выполняет запрос к контроллеру?
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
Кто-либо может видеть, почему мой тупик не работает? Как я сказал, мои тесты только передают, если я удостоверяюсь, что load_user работает, в противном случае весь мой тестовый сбой, который заставляет мой думать, что RSpec не использует тупик, который я создал.
Заглушка load_user
нарушает ваши тесты, потому что заглушка метода нейтрализует его. Когда контроллер вызывает load_user
, он больше не выполняет ваш исходный код. Теперь он просто возвращает то, что вы указали в and_return (...)
(который возвращается в стек обратного вызова ActionController
, который игнорирует все, кроме false
). .
Код вашего контроллера не использует возвращаемое значение этого метода; он использует переменную, созданную внутри it. Поскольку исходный код для метода load_user
не выполняется, переменная экземпляра @user
никогда не создается. (Переменная @user
в ваших тестах видна только вашим тестам.)
Но со всеми другими имеющимися у вас заглушками я не вижу причин, по которым вам может понадобиться заглушить ] load_user
вообще. Пока вы используете заглушку current_user
, чтобы вернуть @user
(что, как я полагаю, выполняется в методе sign_in
), то не должно быть никаких необходимость.
вы также можете попробовать проверить, что заглушка работает, выполнив утверждение вроде
controller.current_user.should == @user