3

我正在尝试解决 Michael Hartl 书籍 Rails v 4.0 第 9.6 章的问题 6。

尽管在 rspec 测试中一切看起来都很好:

  describe "should redirect a logged in user to root url if user tries to hit new in users controller" do
    let(:user) {FactoryGirl.create(:user)}
    before do
      sign_in user
      get new_user_path
    end

    specify{expect(response).to redirect_to(root_url)}
  end

  describe "should redirect a logged in user to root url if user tries to hit create in users controller" do
    let(:params) do {user: {name: "Tester", email: "test@example.com", password: "password",
                            password_confirmation: "password"}}
    end
    let(:user) {FactoryGirl.create(:user)}

    before do
      sign_in user
      post users_path, params
    end

    specify{expect(response).to redirect_to(root_url)}
  end

这是我的控制器片段:

class UsersController < ApplicationController
before_action :is_signed_in, only: [:new, :create]
def new
  @user = User.new
end

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

 private
  def is_signed_in
    redirect_to(root_url) if signed_in?
  end
end

utility.rb 中的 sign_in 方法

def sign_in(user, options = {})
  if options[:no_capybara]
    # Signin when not using capybara
    remember_token = User.new_remember_token
    cookies[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
  else
    visit signin_path
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Sign In"
  end
end

但是我的测试用例因以下错误而失败:

Failures:

  1) Authentication signin with valid information should redirect a logged in user to root url if user tries to hit create in users controller
   Failure/Error: specify{expect(response).to redirect_to(root_url)}
   Expected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/users/2>.
   Expected "http://www.example.com/" to be === "http://www.example.com/users/2".
 # ./spec/requests/authentication_pages_spec.rb:69:in `block (5 levels) in <top (required)>'

  2) Authentication signin with valid information should redirect a logged in user to root url if user tries to hit new in users controller
 Failure/Error: specify{expect(response).to redirect_to(root_url)}
   Expected response to be a <redirect>, but was <200>
 # ./spec/requests/authentication_pages_spec.rb:55:in `block (5 levels) in <top (required)>'

Finished in 5.22 seconds
95 examples, 2 failures

Failed examples:

rspec ./spec/requests/authentication_pages_spec.rb:69 # Authentication signin with valid information should redirect a logged in user to root url if user tries to hit create in users controller
rspec ./spec/requests/authentication_pages_spec.rb:55 # Authentication signin with valid information should redirect a logged in user to root url if user tries to hit new in users controller

Randomized with seed 58509

我试图调试,但无法找出确切的问题。谁可以帮我这个事 ?

编辑:1:添加 route.rb Routes.rb

    SampleApp::Application.routes.draw do
      resources :users
      resources :sessions, only: [:new, :create, :destroy]
      root "static_pages#home"
      match '/help', to: "static_pages#help", via: 'get'
      match '/about', to: "static_pages#about", via: 'get'
      match '/contact', to: "static_pages#contact", via: 'get'
      match '/signup', to: "users#new", via: 'get'
      match '/signin', to: "sessions#new", via: 'get'
      match '/signout', to: "sessions#destroy", via: 'delete'
   end

编辑 2 我正在用水豚测试它。

宝石文件

group :test do
  gem 'selenium-webdriver', '2.35.1'
  gem 'capybara', '2.1.0'
  gem 'growl', '1.0.3'
  gem 'factory_girl_rails', '4.2.1'
  gem 'database_cleaner', '<1.1.0'
  gem "launchy", "2.3.0"
  gem 'cucumber-rails', '1.4.0', :require => false
end

session_helper.rb

module SessionsHelper

  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
    self.current_user = user
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    remember_token = User.encrypt(cookies[:remember_token])
    @current_user ||= User.find_by(remember_token: remember_token)
  end

  def signed_in?
    !current_user.nil?
  end

  def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end

  def current_user?(user)
    current_user == user
  end

  def store_location
    session[:return_to] = request.url if request.get?
  end

  def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    session.delete(:return_to)
  end

  def signed_in_user
    unless signed_in?
      store_location
      redirect_to signin_url, notice: "Please sign in."
    end
  end
end
4

1 回答 1

1

我相信你错过了这个:

no_capybara: true

所以它应该是这样的:

before do
  sign_in user, no_capybara: true
  get new_user_path
end

和这个:

before do
  sign_in user, no_capybara: true
  post users_path, params
end

这是我和你的唯一区别。希望它有效!

于 2013-09-20T21:02:41.947 回答