首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个属性在rspec测试中评估之前丢失了?

为什么这个属性在rspec测试中评估之前丢失了?
EN

Stack Overflow用户
提问于 2016-12-08 15:27:02
回答 1查看 357关注 0票数 0

我使用的设计,并已重写注册控制器,以允许用户“软删除”在这里的说明:设计/wiki/如何:-软-删除-a-用户

我在代码中放置了一些puts命令来跟踪测试,我的rspec结果如下所示:

代码语言:javascript
复制
    10:00:30 - INFO - Running: spec/controllers/users/registrations_controller_spec.rb
    ..
>   BEFORE: id:2, deleted_at:
>    -- model: id:2, deleted_at:2016-12-08 15:00:35 UTC
>    -- controller: id:2, deleted_at:2016-12-08 15:00:35 UTC
>   AFTER: id:2, deleted_at:
    F..

    Failures:

      1) Users::RegistrationsController GET #destroy sets 'deleted_at' date for user
         Failure/Error: expect(user.deleted_at).to_not be_nil

           expected: not nil
                got: nil
         # ./spec/controllers/users/registrations_controller_spec.rb:44:in `block (3 levels) in <top (required)>'

    Finished in 0.37438 seconds (files took 3.7 seconds to load)
    5 examples, 1 failure

puts所示,我的用户首先将deleted_at字段设置为null。模型将deleted_at设置为当前时间,控制器确认日期已设置,但当我到达测试中的expect()语句时,user.deleted_at已返回到nil。这似乎是我的测试中的一个问题,因为应用程序功能正常。

/spec/controllers/users/registrations_controller_spec.rb

代码语言:javascript
复制
  require 'rails_helper'
  require 'factory_girl_rails'

  RSpec.describe Users::RegistrationsController, type: :controller do    
     include Devise::Test::ControllerHelpers

     describe "GET #destroy" do

        it "sets 'deleted_at' date for user" do
          request.env["devise.mapping"] = Devise.mappings[:user]

          # sign-in user
          user = FactoryGirl.create(:user_for_account_update)
          sign_in(user, scope: :user) # note: does not verify correct password

          # soft-delete user
          puts "BEFORE: id:#{user.id}, deleted_at:#{user.deleted_at}"
          delete :destroy, {:id => user.id}
          puts "AFTER: id:#{user.id}, deleted_at:#{user.deleted_at}"

          expect(user.deleted_at).to_not be_nil
        end
     end
  end

/spec/factories/user.rb

代码语言:javascript
复制
require 'ffaker'

FactoryGirl.define do
  factory :user do |u|
    @pass = "password"

    name FFaker::Name.name
    email { |me| "#{name.to_s.gsub(/\s/,'.')}_#{rand(1000).to_s}@testing.com" }
    password @pass

    factory :user_for_account_update do
      password_confirmation @pass
      confirmed_at Date.today
    end
  end
end

/app/models/user.rb

代码语言:javascript
复制
  ...

  # instead of deleting, indicate the user requested a delete & timestamp it
  def soft_delete
    update_attribute(:deleted_at, Time.current)
    puts " -- model: id:#{id}, deleted_at:#{deleted_at.to_s}"
  end

  ...

/app/controllers/users/registrations_controller.rb

代码语言:javascript
复制
# This class overrides devise's registration controller.  All
# other devise actions remain (I believe) handled as usual by 
# devise.  I think it is the route that does that by specifying
# this controller specifically for the purpose of registrations
#
# see also: http://stackoverflow.com/questions/3546289
class Users::RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters, if: :devise_controller?

  # SOFT DELETE /resource
  # Follows devise guide: https://github.com/plataformatec/devise/wiki/How-to:-Soft-delete-a-user-when-user-deletes-account
  def destroy
    resource.soft_delete
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
    set_flash_message :notice, :destroyed if is_flashing_format?
    yield resource if block_given?
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
    puts " -- controller: id:#{resource.id}, deleted_at:#{resource.deleted_at}"
  end

  protected

  # we have to explicitly permit params in overridden controllers like this
  # see https://github.com/plataformatec/devise#strong-parameters
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up) do |u|
      u.permit(:name, :email, :password, :password_confirmation)
    end
    devise_parameter_sanitizer.permit(:account_update) do |u|
      u.permit(:name, :email, :password, :password_confirmation, :current_password)
    end
  end
end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-08 17:31:04

您使用的是在控制器操作之前创建的user,因此它具有缓存的值(包括deleted_at)。

您可以使用user.reload从DB获取更新的属性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41042987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档