RSpec 示例不适用于 before_validation

RSpec example not working with before_validation

我有一个相当简单的模型正在保存,但是遇到 RSpec 失败,我找不到解决方案。我也在用 shoulda gem.

CharacterSheet 模型:

class CharacterSheet < ActiveRecord::Base
  validates :character_name, :player_name, :strength, :strength_modifier, presence: true

  before_validation :calculate_strength_modifier, on: :create

  def calculate_strength_modifier
    self.strength_modifier = ((self.strength - 10)/2).floor
  end

end

RSpec 示例:

RSpec.describe CharacterSheet, type: :model do

  let(:character_sheet) { CharacterSheet.new(character_name: "Test Character",
                                                player_name: "Michael",
                                                   strength: 18) }

  describe "attributes" do

    it { expect(character_sheet).to validate_presence_of :character_name }
    it { expect(character_sheet).to validate_presence_of :player_name }
    it { expect(character_sheet).to validate_presence_of :strength }
    it { expect(character_sheet).to validate_presence_of :strength_modifier }

    it "saves attributes" do
      character_sheet.save!
      expect(character_sheet).to be_valid
    end

  end
end

这些是我遇到的失败:

失败:

  1) CharacterSheet attributes should require strength to be set
     Failure/Error: it { expect(character_sheet).to validate_presence_of :strength }
     NoMethodError:
       undefined method `-' for nil:NilClass

  2) CharacterSheet attributes should require strength_modifier to be set
     Failure/Error: it { expect(character_sheet).to validate_presence_of :strength_modifier }
       Expected errors to include "can't be blank" when strength_modifier is set to nil,
       got no errors

如果我在 rails 控制台中手动创建一条记录,它看起来是正确的。只是测试失败了。

此外,如果我删除 before_validation 调用。唯一失败的是预期的 "saves attributes" 示例。

好的,首先您必须了解 validate_presence_of 匹配器...将该属性的值设置为 nil...并测试您是否收到错误。

想一想这对您的验证前意味着什么。你没有任何力量......然后在你进行验证之前触发验证前触发器......并且你试图从一无所有中拿走10并且它爆炸了。

我敢打赌,您应该在其中进行测试,以确保它不会做一些愚蠢的事情。例如:

def calculate_strength_modifier
  self.strength_modifier = ((self.strength - 10)/2).floor if self.strength.present?
end