Por que meus testes do RSpec estão falhando, mas meu aplicativo está funcionando?

Eu acabei de terminarcapítulo 10 do Tutorial Ruby on Rails, adicionando a capacidade de editar / atualizar, indexar e destruir usuários. Tudo parece estar funcionando corretamente no meu aplicativo, mas muitos dos meus testes estão falhando quando executo o RSpec.

Eu tenho o users_controller_spec configurado exatamente como o livro faz e meu código de aplicativo também é o mesmo. Um problema pode ser o fato de eu estar usando o Rails 3.1.1 em oposição ao Rails 3.0, que ele usa no livro? Realmente não foi um problema para testes anteriores, apenas ocasionalmente para algumas linhas de código diferentes. Os problemas começaram a aparecer depois que eu comeceiseção 10.2.1.

Aqui está a lista de erros que estou vendo e informe-me se precisar de mais informações. Obrigado

1) UsersController GET 'index' for signed-in users should be successful
 Failure/Error: response.should be_success
   expected success? to return true, got false
 # ./spec/controllers/users_controller_spec.rb:31:in `block (4 levels) in <top (required)>'

2) UsersController GET 'index' for signed-in users should have the right title
 Failure/Error: response.should have_selector("title", :content => "All users")
   expected following output to contain a <title>All users</title> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:36:in `block (4 levels) in <top (required)>'

3) UsersController GET 'index' for signed-in users should have an element for each user
 Failure/Error: response.should have_selector("li", :content => user.name)
   expected following output to contain a <li>Richard Berger</li> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:42:in `block (5 levels) in <top (required)>'
 # ./spec/controllers/users_controller_spec.rb:41:in `each'
 # ./spec/controllers/users_controller_spec.rb:41:in `block (4 levels) in <top (required)>'

4) UsersController GET 'index' for signed-in users should paginate users
 Failure/Error: response.should have_selector("div.pagination")
   expected following output to contain a <div.pagination/> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:48:in `block (4 levels) in <top (required)>'

5) UsersController GET 'edit' should be successful
 Failure/Error: response.should be_success
   expected success? to return true, got false
 # ./spec/controllers/users_controller_spec.rb:184:in `block (3 levels) in <top (required)>'

6) UsersController GET 'edit' should have the right title
 Failure/Error: response.should have_selector("title", :content => "Edit user")
   expected following output to contain a <title>Edit user</title> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:189:in `block (3 levels) in <top (required)>'

7) UsersController GET 'edit' should have a link to change the Gravatar
 Failure/Error: response.should have_selector("a", :href => gravatar_url, :content => "change")
   expected following output to contain a <a href='http://gravatar.com/emails'>change</a> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:195:in `block (3 levels) in <top (required)>'

8) UsersController PUT 'update' failure should render the 'edit' page
 Failure/Error: response.should render_template('edit')
   expecting <"edit"> but rendering with <"">
 # ./spec/controllers/users_controller_spec.rb:214:in `block (4 levels) in <top (required)>'

9) UsersController PUT 'update' failure should have the right title
 Failure/Error: response.should have_selector("title", :content => "Edit user")
   expected following output to contain a <title>Edit user</title> tag:
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
   <html><body>You are being <a href="http://test.host/signin">redirected</a>.</body></html>
 # ./spec/controllers/users_controller_spec.rb:219:in `block (4 levels) in <top (required)>'

10) UsersController PUT 'update' success should change the user's attributes
 Failure/Error: @user.name.should  == @attr[:name]
   expected: "New Name"
        got: "Richard Berger" (using ==)
 # ./spec/controllers/users_controller_spec.rb:232:in `block (4 levels) in <top (required)>'

11) UsersController PUT 'update' success should redirect to the user show page
 Failure/Error: response.should redirect_to(user_path(@user))
   Expected response to be a redirect to <http://test.host/users/1> but was a redirect to <http://test.host/signin>
 # ./spec/controllers/users_controller_spec.rb:238:in `block (4 levels) in <top (required)>'

12) UsersController PUT 'update' success should have a flash message
 Failure/Error: flash[:success].should =~ /updated/
   expected: /updated/
        got: nil (using =~)
 # ./spec/controllers/users_controller_spec.rb:243:in `block (4 levels) in <top (required)>'

13) UsersController authentication of edit/update pages for signed-in users should require matching users for 'edit'
 Failure/Error: response.should redirect_to(root_path)
   Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/signin>
 # ./spec/controllers/users_controller_spec.rb:276:in `block (4 levels) in <top (required)>'

14) UsersController authentication of edit/update pages for signed-in users should require matching users for 'update'
 Failure/Error: response.should redirect_to(root_path)
   Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/signin>
 # ./spec/controllers/users_controller_spec.rb:281:in `block (4 levels) in <top (required)>'

15) UsersController DELETE 'destroy' as a non-admin user should protect the page
 Failure/Error: response.should redirect_to(root_path)
   Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/signin>
 # ./spec/controllers/users_controller_spec.rb:303:in `block (4 levels) in <top (required)>'

16) UsersController DELETE 'destroy' as an admin user should destroy the user
 Failure/Error: lambda do
   count should have been changed by -1, but was changed by 0
 # ./spec/controllers/users_controller_spec.rb:315:in `block (4 levels) in <top (required)>'

17) UsersController DELETE 'destroy' as an admin user should redirect to the users page
 Failure/Error: response.should redirect_to(users_path)
   Expected response to be a redirect to <http://test.host/users> but was a redirect to <http://test.host/signin>
 # ./spec/controllers/users_controller_spec.rb:322:in `block (4 levels) in <top (required)>'

ATUALIZAR

Solucionei 2 dos erros, mas a maioria ainda persiste. Um problema parece ser que, quando o teste está tentando "obter: índice", ele não encontra a página correta devido a um redirecionamento (para a página / signin). Não institui nenhum redirecionamento (de propósito, de qualquer maneira), mas talvez alguém tenha uma idéia de como isso pode ter acontecido e como pode ser corrigido?

UPDATE # 2:

solicitação do @Per @ bkempner, aqui está o código relevante do users_controller_spec e do users_controller (users_controller_spec primeiro). Muito código, mas muitos erros ...:

describe "for signed-in users" do

  before(:each) do
    @user = test_sign_in(Factory(:user))
    second = Factory(:user, :email => "[email protected]")
    third  = Factory(:user, :email => "[email protected]")

    @users = [@user, second, third]
    30.times do
      @users << Factory(:user, :email => Factory.next(:email))
    end
  end

  it "should be successful" do
    get :index
    response.should be_success
  end

  it "should have the right title" do
    get :index
    response.should have_selector("title", :content => "All users")
  end

  it "should have an element for each user" do
    get :index
    @users[0..2].each do |user|
      response.should have_selector("li", :content => user.name)
    end
  end

  it "should paginate users" do
    get :index
    response.should have_selector("div.pagination")
    response.should have_selector("span.diabled", :content => "Previous")
    response.should have_selector("a", :href => "/users?page=2", :content => "2")
    response.should have_selector("a", :href => "/users?page=2", :content => "Next")
  end
end

describe "GET 'edit'" do

  before(:each) do
    @user = Factory(:user)
    test_sign_in(@user)
  end

  it "should be successful" do
    get :edit, :id => @user
    response.should be_success
  end

  it "should have the right title" do
    get :edit, :id => @user
    response.should have_selector("title", :content => "Edit user")
  end

  it "should have a link to change the Gravatar" do
    get :edit, :id => @user
    gravatar_url = "http://gravatar.com/emails"
    response.should have_selector("a", :href => gravatar_url, :content => "change")
  end
end

describe "PUT 'update'" do

  before(:each) do
    @user = Factory(:user)
    test_sign_in(@user)
  end

  describe "failure" do

    before(:each) do
      @attr = { :email => "", :name => "", :password => "", :password_confirmation => "" }
    end

    it "should render the 'edit' page" do
      put :update, :id => @user, :user => @attr
      response.should render_template('edit')
    end

    it "should have the right title" do
      put :update, :id => @user, :user => @attr
      response.should have_selector("title", :content => "Edit user")
    end
  end

  describe "success" do

    before(:each) do
      @attr = { :name => "New Name", :email => "[email protected]", :password => "barbaz", :password_confirmation => "barbaz" }
    end

    it "should change the user's attributes" do
      put :update, :id => @user, :user => @attr
      @user.reload
      @user.name.should  == @attr[:name]
      @user.email.should == @attr[:email]
    end

    it "should redirect to the user show page" do
      put :update, :id => @user, :user => @attr
      response.should redirect_to(user_path(@user))
    end

    it "should have a flash message" do
      put :update, :id => @user, :user => @attr
      flash[:success].should =~ /updated/
    end
  end
end

describe "authentication of edit/update pages" do

  describe "for signed-in users" do

    before(:each) do
      wrong_user = Factory(:user, :email => "[email protected]")
      test_sign_in(wrong_user)
    end

    it "should require matching users for 'edit'" do
      get :edit, :id => @user
      response.should redirect_to(root_path)
    end

    it "should require matching users for 'update'" do
      get :update, :id => @user, :user => {}
      response.should redirect_to(root_path)
    end
  end
end

describe "DELETE 'destroy'" do

  before(:each) do
    @user = Factory(:user)
  end

  describe "as a non-admin user" do
    it "should protect the page" do
      test_sign_in(@user)
      delete :destroy, :id => @user
      response.should redirect_to(root_path)
    end
  end

  describe "as an admin user" do

    before(:each) do
      admin = Factory(:user, :email => "[email protected]", :admin => true)
      test_sign_in(admin)
    end

    it "should destroy the user" do
      lambda do
        delete :destroy, :id => @user
      end.should change(User, :count).by(-1)
    end

    it "should redirect to the users page" do
      delete :destroy, :id => @user
      response.should redirect_to(users_path)
    end
  end
end

E agora todo o user_controller:

class UsersController < ApplicationController
before_filter :authenticate, :only => [:index, :edit, :update, :destroy]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user,   :only => :destroy

def index
  @title = "All users"
  @users = User.paginate(:page => params[:page])
end

def show
  @user = User.find(params[:id])
  @title = @user.name
end

def new
  @user = User.new
  @title = "Sign up"
end

def create
  @user = User.new(params[:user])
  if @user.save
    sign_in @user
    flash[:success] = "Welcome to the Sample App!"
    redirect_to @user
  else
    @title = "Sign up"
    render 'new'
  end
end

def edit
  @title = "Edit user"
end

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    flash[:success] = "Profile updated"
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def destroy
  User.find(params[:id]).destroy
  flash[:success] = "User destroyed."
  redirect_to users_path
end

private

  def authenticate
    deny_access unless signed_in?
  end

  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_path) unless current_user?(@user)
  end

  def admin_user
    redirect_to(root_path) unless current_user.admin?
  end
end

questionAnswers(6)

yourAnswerToTheQuestion