【问题标题】:Rspec test a Validation that prevents attribute change after initial create (Rails 4, rspec 3)Rspec 测试在初始创建后防止属性更改的验证(Rails 4,rspec 3)
【发布时间】:2015-09-20 08:54:04
【问题描述】:

我有一个模型,我在其中实施了验证以防止在设置初始值后发生更改。

它是这样工作的:

models/deal.rb

validate :quantity_not_changeable

def quantity_not_changeable
      if quantity_changed? && self.persisted?
        errors.add(:quantity,"Change of quantity is not allowed. Delete and re-create the deal.")
      end
    end

这适用于我的应用程序。但我正在尝试使用 Rspec 进行测试,但没有成功。

我尝试对此进行测试,但测试失败。

describe Deal do

  let(:admin_user) { FactoryGirl.create(:admin_user) }

  before(:each) do
    @attr = {
      title:                              "Neque porro quisquam est qui dolorem",
      description:                        "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum",
      quantity:  10
    }
  end

describe "my test" do

it "fails if initial quantity is changed" do 
      msg_error = "Change of the initially defined qty is impossible"
      hash = @attr.merge(quantity: 5)
      deal = Deal.new(hash)
      expect(deal).to have(1).errors_on(:quantity)      
    end
end

但我收到此 rspec 错误:

Failure/Error: expect(deal).to have(1).errors_on(:quantity)
       expected 1 errors on :quantity, got 0

如何做到这一点并真正测试改变数量是不可能的?

编辑

我现在明白为什么测试失败了,但不知道如何处理。

如果我删除 self.persisted?从下面的代码中,我使用的测试通过了。所以问题出在持久化?

def quantity_not_changeable
          if quantity_changed? 
            errors.add(:quantity,"Change of quantity is not allowed. Delete and re-create the deal.")
          end
        end

但我不想删除它,因为我确实需要它:我只想在字段已经有值时阻止更改它,所以我想忽略新记录。

【问题讨论】:

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


    【解决方案1】:

    您应该编辑模型:

    validate :quantity_not_changeable, on: :update
    
    def quantity_not_changeable
      if quantity_changed?
        errors.add(:quantity,"Change of quantity is not allowed. Delete and re-create the deal.")
      end
    end
    

    然后在它里面声明:

    it "fails if initial quantity is changed" do 
      msg_error = "Change of the initially defined qty is impossible"
      deal = Deal.create!(@attr)
      deal.update(quantity: 5)
      expect(deal).to have(1).errors_on(:quantity)      
    end
    

    【讨论】:

    • 感谢您的回答,但仍然无法正常工作。我仍然遇到同样的错误。
    • 很抱歉,分别更改后有检查我们首先需要创建对象,然后进行更新和数量更改?将是真的,并且已经添加了错误。请记住,新方法没有验证,但创建或更新方法会进行验证。
    • 嗨德沃尔。我看不出与 Alexei 的回答有什么不同,而且他的回答没有用。
    • 检查我的编辑:追踪错误的来源:它是“持续存在的”
    • 嗨,马修。查看我编辑的答案。当使用简单的验证功能时,在create 方法之后运行验证并且它没有将条目保存到数据库并且它的持久化设置为false。我们只需将哈希传递给validate 方法,仅用于update。此外,您不需要在persisted? 条件下进入,因为在第一次创建后它会被持久化。
    【解决方案2】:

    您需要创建您的Deal,这样您的persisted? 检查才会起作用,然后然后更新您的quantity 属性,这样您的第二次检查quantity_changed? 也将起作用: p>

    it "fails if initial quantity is changed" do 
      msg_error = "Change of the initially defined qty is impossible"
      deal = Deal.create(@attr)
      deal.update(quantity: 5)
      expect(deal).to have(1).errors_on(:quantity)      
    end
    

    【讨论】:

    • @Alexei,尝试了你的方法,但仍然得到相同的错误“预期 1 个错误:数量,得到 0”。与真实应用程序一样非常令人沮丧,当我手动尝试更改它时,我确实看到我的验证有效,因为我无法更改值。
    • 检查我的编辑:追踪错误的来源:它是“持续存在的”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多