2013-02-11 68 views
8

我有一個與用戶模型交互的請求規範。我想確保具有Admin角色的用戶可以創建/編輯/銷燬用戶。我現在遇到編輯操作不更新用戶的問題。當我手動完成網站本身的操作時,一切正常,但測試無法更新用戶。爲什麼此rspec請求規範不更新模型?

這裏是我的規格:

it 'edits a user' do 
    @user = FactoryGirl.create(:user) 
    visit new_user_session_path unless current_path == new_user_session_path 
    fill_in "Email", :with => @user.email 
    fill_in "Password", :with => @user.password 
    click_button "Sign In" 
    user_to_edit = FactoryGirl.create(:user, first_name: "John", last_name: "Smith") 
    visit edit_user_path(user_to_edit) unless current_path == edit_user_path(user_to_edit) 
    fill_in 'user_last_name', with: "Changed" 
    expect{ 
    click_button "Do it" 
    }.to change { user_to_edit.last_name }.from("Smith").to("Changed") 
    page.should have_content "John Changed" 
end 

,我得到的錯誤是:

Failure/Error: expect{ 
     result should have been changed to "Changed", but is now "Smith" 

如果我改變測試的最後幾行這樣的:

fill_in 'user_last_name', with: "Changed" 
    click_button "Do it" 
    page.should have_content "John Changed" 

然後測試成功。這看起來不正確,因爲如果user_to_edit沒有更新,頁面不應該顯示「John Changed」。

我的刪除請求規範工作正常:

it "deletes a user" do 
    @user = FactoryGirl.create(:user) 
    visit new_user_session_path unless current_path == new_user_session_path 
    fill_in "Email", :with => @user.email 
    fill_in "Password", :with => @user.password 
    click_button "Sign In" 
    user_to_delete = FactoryGirl.create(:user, first_name: "John", last_name: "Smith") 
    visit users_path unless current_path == users_path 
    expect{ 
    within ".user_#{user_to_delete.id}" do 
     click_link 'Delete' 
    end 
    }.to change(User,:count).by(-1) 
    page.should_not have_content "John Smith" 
end 

我有一個用戶模式:

class User < ActiveRecord::Base 
    ROLES = %w[renter landlord admin] 
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable 
    attr_accessible :email, :password, :password_confirmation :first_name, :last_name, :role 

    validates :password, :presence => true, :on => :create 
    validates :first_name, :presence => true 
    validates :last_name, :presence => true 

    before_save :set_phones 

    def set_phones 
    self.fax = Phoner::Phone.parse(self.fax).format("%a%n") unless self.fax.blank? 
    self.land_phone = Phoner::Phone.parse(self.land_phone).format("%a%n") unless land_phone.blank? 
    self.mobile_phone = Phoner::Phone.parse(self.mobile_phone).format("%a%n") unless mobile_phone.blank? 
    end 
end 

我有這樣的工廠:

require 'faker' 

FactoryGirl.define do 
    factory :user do |f| 
    f.first_name { Faker::Name.first_name } 
    f.last_name { Faker::Name.last_name } 
    f.email {Faker::Internet.email} 
    f.password { "oq2847hrowihgfoigq278o4r7qgo4" } 
    f.role { "admin" } 
    end 
end 

我在我的用戶這些行動控制器:

def edit 
    @user = User.find_by_id(params[:id]) 

    respond_to do |format| 
     format.html 
    end 
    end 

    def update 
    if params[:user][:password].blank? 
     [:password,:password_confirmation].collect{|p| params[:user].delete(p) } 
    end 

    respond_to do |format| 
     if @user.errors[:base].empty? and @user.update_attributes(params[:user]) 
     flash.now[:notice] = "Your account has been updated" 
     format.html { render :action => :show } 
     else 
     format.html { render :action => :edit, :status => :unprocessable_entity } 
     end 
    end 
    end 

routes.rb文件也是相關的,因爲我使用的設計,並有一個自定義的用戶控制器:

devise_for :users, :skip => [:sessions, :registrations] 

    devise_scope :user do 
    get "login" => "devise/sessions#new", :as => :new_user_session 
    post 'login' => 'devise/sessions#create', :as => :user_session 
    delete "logout" => "devise/sessions#destroy", :as => :destroy_user_session 
    get "signup" => "devise/registrations#new", :as => :new_user_registration 
    put "update-registration" => "devise/registrations#update", :as => :update_user_registration 
    delete "delete-registration" => "devise/registrations#destroy", :as => :delete_user_registration 
    get "edit-registration" => "devise/registrations#edit", :as => :edit_user_registration 
    get "cancel-registration" => "devise/registrations#cancel", :as => :cancel_user_registration 
    post "create-registration" => "devise/registrations#create", :as => :user_registration 
    end 

    resources :users, :controller => "users" 
+1

關於爲什麼測試失敗,您還有任何其他信息嗎?例如,可能在更新之前,更新之後將@ user.errors輸出到控制檯,並且更新失敗將是一個好主意。 – Max 2013-02-11 16:04:10

回答

18

你被測試框架如何聰明看:) 愚弄你一定想到分貝進入user_to_edit更改。 user_to_edit是一個局部變量,因此無論您點擊哪個按鈕,user_to_edit.last_name都不會改變。嘗試使用{ user_to_edit.reload.last_name }

+0

呃。當然!現在很明顯,你指出 - 謝謝!另外,感謝您提供'user_to_edit.reload.last_name'建議 - 您也爲我節省了很多麻煩。 – 2013-02-11 16:33:28

+0

你剛剛救了我幾個小時,感謝這個 – 2013-05-31 00:36:39

+0

也節省了我的時間..太棒了! – Aitizazk 2016-02-23 19:34:02

相關問題