为什么这个rspec请求规范不更新模型? [英] Why is this rspec request spec not updating the model?

查看:147
本文介绍了为什么这个rspec请求规范不更新模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有与用户模型交互的请求规范。我想确保具有管理员角色的用户可以创建/编辑/销毁用户。我现在有一个问题,编辑操作不会更新用户。当我手动浏览网站本身的操作时,一切正常,但测试无法更新用户。

I have a requests spec for interactions with the User model. I want to make sure that Users with the Admin role can create/edit/destroy Users. I'm having a problem right now where the Edit action does not update the user. Everything works properly when I manually go through the actions on the site itself, but the tests fail to update the user.

这是我的规格:

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"

如果我更改最后几行的测试:

If I change the last few lines of the test to this:

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

然后测试成功。如果 user_to_edit 未更新,则页面不应显示John Changed。

Then the test succeeds. This doesn't seem right, since the page should not display "John Changed" if user_to_edit was not updated.

我的删除请求规范工作正常:

My Delete request spec works fine:

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

我的用户控制器中有这些操作:

I have these actions in my user controller:

  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并拥有自定义的用户控制器:

The routes.rb file is also relevant, since I'm using Devise and have a custom Users Controller:

  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"


推荐答案

你被智能测试框架看看:)
肯定你期望 user_to_edit 数据库条目更改。 user_to_edit 是一个局部变量,所以 user_to_edit.last_name 不会改变,无论你点击什么按钮。尝试使用 {user_to_edit.reload.last_name}

you are fooled by how smart testing frameworks look :) surely you expect the db entry for user_to_edit to change. user_to_edit is a local variable so user_to_edit.last_name will not change no matter what buttons you click. try with { user_to_edit.reload.last_name }

这篇关于为什么这个rspec请求规范不更新模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆