我有与User模型交互的请求规范。我想确保具有Admin角色的用户可以创建/编辑/销毁用户。我现在遇到问题,编辑操作不会更新用户。当我手动浏览网站上的操作时,一切正常,但测试无法更新用户。
这是我的规格:
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并拥有自定义用户控制器:
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"
答案 0 :(得分:18)
你被智能测试框架的外观所迷惑:)
当然你希望user_to_edit
的 db entry 能够改变。 user_to_edit
是一个局部变量,因此无论您点击哪个按钮,user_to_edit.last_name
都不会更改。试试{ user_to_edit.reload.last_name }