0

我已经为此苦苦挣扎了几个小时,但我在任何地方都找不到答案。

基本上我正在使用 shoulda 为我的模型编写规范,并且出于某种原因,即使我的 let 工作正常并且实际应用程序工作正常(手动确认并使用请求规范),如果我包括:

it { expect(user).to validate_uniqueness_of :email }

在我的描述块中,我将收到以下错误:

1) User attributes should require case sensitive unique value for email
 Failure/Error: it { expect(user).to validate_uniqueness_of :email }
 RuntimeError:
   Password digest missing on new record
 # ./spec/models/user_spec.rb:14:in `block (3 levels) in <top (required)>'

我已经到了解决这个规范让我退缩的地步,这从来都不是一件好事,因为实施已经奏效了。

如果有人可以在这里帮助我,那就太好了,因为我真的不想为了让事情顺利进行而开始跳过由于某种不明原因而失败的测试。

我觉得好像 rspec 正在“忽略”调用 has_secure_password 以保存摘要的 before 方法,但我不确定。我只是假设,因为如果请求规范工作正常,这是在做我不知道的事情。

我正在使用导轨 4.0.0

以下是与此相关的代码。我很感激任何帮助。谢谢

user_spec.rb

require  'spec_helper'

describe User do

  let(:user) { 
    user = User.new(:email => 'example@example.com', 
                    :username => 'theo', 
                    :password => 'secretpass',
                    :password_confirmation => 'secretpass')}

  describe "attributes" do

    it { expect(user).to validate_presence_of :email } 
    it { expect(user).to validate_uniqueness_of :email }

    it { expect(user).to validate_presence_of :username }
    it { expect(user).to validate_uniqueness_of :username }

    it "saves are saved" do
      user.save!
      expect(user).to be_valid
    end

  end  


end

用户.rb

class User < ActiveRecord::Base
  has_secure_password


  validates :email, :username, presence: true, uniqueness: true
  validates :password, presence: true, :on => :create


end

users_controller.rb

class UsersController < ApplicationController
  def index
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to root_path, :notice => 'You have successfully signed up.'
    else
      render 'new'
    end
  end

  private

  def user_params
    params.require(:user).permit(:email, :username, :password, :password_confirmation)
  end
end
4

3 回答 3

5

请确保您的用户架构中存在密码摘要,详细信息请参见此处

create_table “users”, force: true do |t|
    ……
    t.text     “password_digest”
    …..
end

如果它在您的开发中有效但无法测试,请检查您是否在测试环境中执行 rake db:migration,我的意思是RAILS_ENV=test rake db:migrate


!!!已更新——与shouda-matchersgocha相关

这似乎是一个错误shoulda-matchers,因为当你这样做时,测试将通过:

it "should be validate uniq of email " do
    user.save
    expect(user).to validate_uniqueness_of :email
end

我这样做的原因user.save是因为这个 ,否则它会为你创建一个记录,这将导致你得到的错误:

# https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb#L126
 def create_record_in_database(options = {})
      if options[:nil_value]
        value = nil
      else
        value = "arbitrary_string"
      end

      @subject.class.new.tap do |instance|
        instance.send("#{@attribute}=", value)
        instance.save(:validate => false) # the error happens here, not in your code
      end
    end

所以最重要的是,这可能是一个错误shouda-matchers,虽然我没有时间弄清楚如何修复它,现在你可以使用这个方法来解决这个问题,或者使用其他方法来测试它。

希望能帮助到你 :-)

于 2013-07-14T00:17:42.620 回答
0

可能是 shoulda-matchers 中的一个错误,可能与这个有关https://github.com/thoughtbot/should-matchers/issues/290

干杯

于 2013-07-15T11:59:19.520 回答
0

您的问题的答案在这里:https ://github.com/thoughtbot/should-matchers/issues/371

简而言之,这是根本问题:

看来Rails 4 版本has_secure_password增加了一个before_create 来保证password_digest填写;然而,Rails 3 版本没有这个检查。

于 2013-10-21T15:25:02.073 回答