2014-09-20 66 views
0

您好朋友我有事要先承認,我以前的帳戶被禁止提問,從現在開始,我會盡量讓問題更清晰準確!使用Rspec進行測試會出錯,但使用瀏覽器進行測試可以正常工作

我正在研究Hartl的Ruby on Rails教程,我被困在chapter 9.2.2 Requiring the right user``「列表9.13測試編輯和更新操作需要合適的用戶」幾天。我做了大量的研究,我回過頭來看章節,沒有起作用,似乎沒有人有我現在的問題。讓我詳細解釋一下。

錯誤:

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: '[email protected]') } 
     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 motherfuckers' 
     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

你有什麼版本的Hartl教程?在我的副本上甚至在他的網頁上都沒有第9.13章(https://www.railstutorial.org/book/updating_and_deleting_users) – pawel7318 2014-09-21 14:48:26

+0

Hi Pawel,我有Hartl教程的這個版本。非常感謝你回覆我,我看到了希望!其在9.2.2要求合適的用戶要求登錄用戶https://www.railstutorial.org/book/updating_and_deleting_users – Snailwalker 2014-09-21 14:50:42

+0

它在9.2.2章節列表9.13,我剛剛修改了這個問題,謝謝 – Snailwalker 2014-09-21 14:54:33

回答

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,這在我嘗試運行時會阻止測試運行。

+0

非常感謝你,現在讓我們感受到了一切!我一定會再回去做測試,但是自那以後我一直在跳過測試,現在我差不多完成了整本書,之後我會讀一本關於「Rspec」的獨立書籍,再次感謝你!你只是把我放在正確的軌道上。 :)我代表14億中國人祝你最好! – Snailwalker 2014-09-24 04:56:05

+0

我想通了你爲什麼沒有得到一個SyntaxError的缺失結束。 spec/support/utilities.rb中的最後一個方法定義有一個額外的'end',它看起來像是最後一個def的一部分,因爲最後一個方法的縮進被完全搞砸了。如果您使用自動縮進的計算機編程文本編輯器,那麼您應該瞭解何時出現錯誤(如缺失結束),因爲當您鍵入下一行時,縮進將不會達到正確的級別。這是一個警告,您需要查看以前的代碼並找出代碼出了什麼問題。 – 7stud 2014-09-24 16:37:46

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')}/) 

無論其...錯誤信息你得到的是更深層次的東西......它表示你傳遞了一個零而不是一個正則表達式......這意味着full_title('Edit user')正在評估爲零而不是實際的字符串。

如果您使用我上面的示例...規範將可能仍然失敗...所以你必須弄清楚爲什麼full-title('Edit user')返回零,並首先修復。

+0

感謝您回答這個問題!我真的很感激 !我已經被這個錯誤困住了將近10天,之後我決定繼續前進,現在我已經在第10章的末尾,從那時起我一直在跳過rspec測試,在完成閱讀教程之後,我會回去讀一本關於rspec的書,我不確定我是否做得對,但你的回答可以幫助我更好地理解rspec。非常感謝你! – Snailwalker 2014-09-23 02:59:44

+0

** full_title('編輯用戶')不是正則表達式...它是頁面上的一些內容。所以它真的不是正確的使用期望...匹配**雖然,我可以找到沒有文檔(或谷歌上的任何東西),match()確實需要一個String參數,這是ROR Tut使用參數match()。 – 7stud 2014-09-24 05:20:49

+0

好的......但是如果你把它傳遞給nil,那麼匹配很可能會發生......而且'full_title('Edit user')'顯然是評估爲零(因爲這就是錯誤信息所說的) – 2014-09-24 07:04:56