Rails唯一性验证测试失败

时间:2015-03-15 08:38:22

标签: ruby-on-rails validation testing unique

我开始使用Rails 4.2,我尝试测试我制作的Item模型的唯一性,我运行了这段代码:

item.rb的:

class Item < ActiveRecord::Base
    attr_accessor :name
    validates :name, uniqueness: true #, other validations...
end

item_test.rb:

require 'test_helper'

class ItemTest < ActiveSupport::TestCase

    def setup
        @item = Item.new(name: "Example Item")
    end

    test "name should be unique" do
        duplicate_item = @item.dup
        @item.save
        assert_not duplicate_item.valid?
    end
end

但是测试没有通过,说assert_not行应该truenil时出现false。我基本上从教程中得到了这段代码,但无法弄清楚它为什么没有通过。有什么帮助吗?

修改:我找不到解决方案,因为我没有定义我在:price操作中定义的@item的其他成员(具体为setup),通过测试。但是现在我不知道如何通过:price成员传递它。以下是item.rb&amp;的完整实现。 item_test.rb。

item.rb的:

class Item < ActiveRecord::Base
    attr_accessor :name, :description, :price
    validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
    validates :description, presence: true,
        length: { maximum: 1000 }
    VALID_PRICE_REGEX = /\A\d+(?:\.\d{0,2})?\z/
    validates :price, presence: true,
        :format => { with: VALID_PRICE_REGEX },
        :numericality => {:greater_than => 0}
end 

item_test.rb:

require 'test_helper'

class ItemTest < ActiveSupport::TestCase

    def setup
        @item = Item.new(name: "Example Item", description: "Some kind of item.", price: 1.00)
    end

    test "name should be unique" do
        duplicate_item = @item.dup
        @item.save
        assert_not duplicate_item.valid?
    end
end

4 个答案:

答案 0 :(得分:4)

针对数据库中已存在的记录执行唯一性验证。并且您的Item.new(name: "Example Item")不在数据库中,直到它被保存。因此,如果您使用Item.create(name: "Example Item"),则测试应该通过。

答案 1 :(得分:2)

Almaron的上述答案是正确的,应该是公认的答案。

我正在添加这个答案来详细阐述它。

测试如下:

require 'test_helper'

class ItemTest < ActiveSupport::TestCase

  def setup
    @item = Item.create(name: "Example Item")
  end

  test "name should be unique" do
    duplicate_item = @item.dup
    assert_not duplicate_item.valid?
  end
end

注意:在验证之前无需保存duplicate_item

答案 2 :(得分:1)

您在编辑中至少发现了一些问题。

问题不在于您使用的是Item.new而不是Item.create问题是当您执行@item.save时@item记录未被保存,因为它有其他验证问题。

你可以试试......

@item.save(validate: false)

...会强制@item写入数据库,但测试并不能真正确定duplicate_item记录无效的原因。

更好的方法是测试您是否有与name ...

相关的错误
require 'test_helper'

class ItemTest < ActiveSupport::TestCase

  def setup
    @item = Item.new(name: "Example Item")
  end

  test "name should be unique" do
    duplicate_item = @item.dup
    @item.save(validate: false)
    duplicate_item.valid? # need this to populate errors
    assert duplicate_item.errors
    assert duplicate_item.errors[:name]
  end
end

答案 3 :(得分:0)

我修复了它,我摆脱了attr_accessor行,然后测试能够访问属性并且能够检测到重复。