RSpec示例不使用before_validation

时间:2015-04-27 03:40:42

标签: ruby-on-rails rspec rspec-rails shoulda

我有一个相当简单的模型被保存,但我得到RSpec失败,我无法找到解决方案。我也在使用the should 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电话。唯一失败的是&#34;保存属性&#34;正如预期的那样。

1 个答案:

答案 0 :(得分:2)

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

想想这对您的验证前的意义。你没有任何力量...然后在你进入验证之前触发了验证之前的触发器...并且你试图从任何东西中取出10并且它会爆炸。

我敢打赌,你应该在那里进行测试,以确保不做愚蠢的事情。例如:

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