使用Rspec测试自定义设计注册控制器更新操作

时间:2014-09-17 04:28:43

标签: ruby-on-rails-4 devise rspec-rails rspec3

我遵循这个设计维基文档,了解如何为注册控制器编写自定义更新操作,以便允许用户编辑其帐户而不提供其密码,除非自己更改密码。 Devise Wiki - How to Allow Users to Edit Account Without Providing a Password.

然而,我无法弄清楚我的Rspec测试中缺少什么来让它通过。以下是相关的代码段:

应用/控制器/ registrations_controller.rb

def update
  @user = User.find(current_user.id)

  successfully_updated = if needs_password?(@user, params)
    @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
  else
    # remove the virtual current_password attribute
    # update_without_password doesn't know how to ignore it
    params[:user].delete(:current_password)
    @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
  end

  if successfully_updated
    set_flash_message :notice, :updated
    # Sign in the user bypassing validation in case their password changed
    sign_in @user, :bypass => true
    redirect_to users_path
  else
    render "edit"
  end
end

规格/工厂/ users.rb的

FactoryGirl.define do
  factory :user do
    email         { Faker::Internet.email }
    password      'XXXXXXXXX'
    first_name    { Faker::Name.first_name }
    middle_name   { Faker::Name.first_name }
    last_name     { Faker::Name.last_name }
  end
end

规格/控制器/ registrations_controller_spec.rb

describe "PUT #update" do
  login_pcp

  let(:user) { FactoryGirl.create(:user, first_name: 'Tom') }

  it "changes user attributes" do
    attrs = FactoryGirl.attributes_for(:user, first_name: 'Jerry')
    attrs.delete(:password)
    put :update, user: attrs
    user.reload
    assigns[:user].should_not be_new_record
    expect(user.first_name).to eq 'Jerry'
    expect(flash[:notice]).to eq 'You updated your account successfully.'
  end
end

当我运行规范时,我收到以下错误:

Failures:

1) RegistrationsController PUT #update changes user attributes
   Failure/Error: expect(user.first_name).to eq 'Jerry'

   expected: "Jerry"
        got: "Tom"

   (compared using ==)
 # ./spec/controllers/registrations_controller_spec.rb:55:in `block (3 levels) in <top (required)>'

由于某种原因,它没有保存更新。我不确定是否应输入密码才能进行更新?任何帮助,将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:0)

现在测试看起来像这样,它通过了:

 var async = require('async');

 app.get('/updateProf', isLoggedIn, function(req, res) {
   async.map(req.user.local.vehicles, function(vehicle, cb){
     Vehicles.findById(vehicle, function(err, vehicle) {
       if (err) cb(err, null);
       console.log('GET Json: ' + vehicle);
       cb(null, vehicle);
     });
   }, function (err, results) {
     console.log(results);
     res.json(results);     
   });

});

答案 1 :(得分:0)

我也遇到过这个问题,但我可以看到,因为当你填写更新表格时,你需要填写一个名为“当前密码”的字段。由于除非您填写该文件,否则不会更新数据。当您使用工厂女孩生成用户数据时,没有此值。我解决了它,如下面的代码所示。

describe "PATCH #UPDATE" do before :each do @user = create(:user) @old_email = @user.email sign_in @user end context 'valid attributes' do it "updates user attributes" do patch :update, id: @user, user: attributes_for(:user, current_password: "password") expect(@user.reload.email).not_to eq(@old_email) end end end