朋友您好我先要承认一下,我以前的帐号被禁止提问,从现在开始,我会尽量让问题更清晰准确!
我正在研究Hartl的ruby on rails教程,我一直坚持chapter 9.2.2 Requiring the right user
`#34;清单9.13测试编辑和更新操作需要合适的用户&#34 ;几天。我已经做了很多研究,我在章节中来回走动,它没有工作,似乎没有人有我现在的问题。让我详细解释一下。
错误:
Authentication authorization as wrong user submitting a GET request to the Users#edit action
Failure/Error: specify { expect(response.body).not_to match(full_title('Edit user')) }
TypeError:
wrong argument type nil (expected Regexp)
# ./spec/requests/authentication_pages_spec.rb:61:in `block (5 levels) in <top (required)>'
Finished in 1.77 seconds
64 examples, 1 failure
我已经与浏览器进行了测试,它运行良好,我试图编辑其他用户。该页面已成功定向到主页!
Github:https://github.com/Snailseason2014/Sample
这里有一些相关的文件:
规格/请求/ authentication_pages_spec.rb
require 'spec_helper'
describe 'Authentication' do
subject { page }
describe 'signin page' do
before { visit signin_path }
it { should have_content('Sign in') }
it { should have_title('Sign in') }
end
describe 'signin' do
before { visit signin_path }
describe 'with invalid information' do
before { click_button 'Sign in' }
it { should have_title('Sign in') }
it { should have_selector('div.alert.alert-error', text: 'Invalid') }
describe 'after visiting another page' do
before { click_link 'Home' }
it { should_not have_selector('div.alert.alter-error') }
end
end
describe 'with valid information' do
let(:user) { FactoryGirl.create(:user) }
before { sign_in user }
it { should have_title(user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
describe 'followed by signout' do
before { click_link 'Sign out' }
it { should have_link('Sign in') }
end
end
end
describe 'authorization' do
describe 'for non-signed-in users' do
let(:user) { FactoryGirl.create(:user) }
describe 'in the Users controller' do
describe 'visiting the edit page' do
before { visit edit_user_path(user) }
it { should have_title('Sign in') }
end
describe 'submitting to the update action' do
before { patch user_path(user) }
specify { expect(response).to redirect_to(signin_path) }
end
end
end
describe 'as wrong user' do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: 'wrong@example.com') }
before { sign_in user, no_capybara: true }
describe 'submitting a GET request to the Users#edit action' do
before { get edit_user_path(wrong_user) }
specify { expect(response.body).not_to match(full_title('Edit user')) }
specify { expect(response).to redirect_to(root_url) }
end
describe 'submitting a PATCH request to the Users#update action' do
before { patch user_path(wrong_user) }
specify { expect(response).to redirect_to(root_url) }
end
end
end
end
应用程序/控制器/ users_controller.rb
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = 'welcome'
redirect_to @user
else
render 'new'
end
end
def edit
# @user = User.find(params[:id])
end
def update
# @user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = 'Profile updated'
redirect_to @user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
# Before filters
def signed_in_user
redirect_to signin_url, notice: 'Please sign in.' unless signed_in?
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
end
答案 0 :(得分:1)
在您的规范中:
expect(response.body).not_to match(full_title('Edit user'))
预期match
exepctation会将某些文本与正则表达式匹配,例如:
expect("hello").to match(/ell/) # => true
expect("hello").to match(/blah/) # => false
full_title('Edit user')
不是正则表达式...它是页面上的一些内容。所以在expect...match
中使用它确实不合适。您可以将任何字符串转换为正则表达式,方法是将其置于//并使用字符串插值语法,例如:
a_string = 'some string'
a_regex = /#{a_string}/
所以在这里你可以使用:
expect(response.body).not_to match(/#{full_title('Edit user')}/)
但是......你得到的错误信息表明更深层次......它表示你传递的是nil而不是正则表达式...这意味着full_title('Edit user')
正在评估为nil而不是一个实际的字符串。
如果您使用上面的示例...规范可能仍然会失败...所以您必须弄清楚为什么full-title('Edit user')
返回nil并首先修复它。
答案 1 :(得分:1)
看起来你跳过了一些练习,特别是第5.6节中的练习,这可以防止你的错误。
在任何情况下,在第5章中,教程都要为要使用的测试定义一个重复的full_title()帮助程序,该帮助程序将放在文件中:
spec/support/utilities.rb
视图使用了原始的full_title()助手。
查看您的spec/support/utilities.rb
文件,您有:
def full_title(page_title)
base_title = 'Ruby on Rails Tutorial Sample App'
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
你能看出什么是错的吗?很明显,您从教程的文本中复制并粘贴了该代码,并且错过了最后一行:end
,这是关闭您在第一行开始的def所必需的。但是,我无法解释为什么在尝试运行测试时没有得到SyntaxError,这会在我尝试时阻止测试运行。