我正在尝试解决Michael Hartl的第9.6章Rails v 4.0中的问题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
utilities.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 我正在用水豚测试它。
的Gemfile
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
答案 0 :(得分: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
这是我与你的对比之间的唯一区别。希望它有效!