【问题标题】:RSpec 2 testing uniquenessRSpec 2 测试唯一性
【发布时间】:2011-09-09 09:29:40
【问题描述】:

我知道我应该测试验证,但我正在学习,所以想知道为什么我的代码不起作用。

环境 Ruby 1.9.2、Rails 3.1、RSpect 2.6.4

我有一个产品模型:

class Product < ActiveRecord::Base
  attr_accessor :title, :description, :image_url, :price

  validates_presence_of :title, :description, :image_url, :message => "can't be blank"
  validates_uniqueness_of :title, :message => "must be unique"
  validates_numericality_of :price, :greater_than_or_equal_to => 0.01, :message => "must be a number greater than 0"
  validates_format_of :image_url, :with => %r{\.(gif|jpg|png)$}i, :message => "is a invalid image file"
end

在 spec/models/product_spec.rb 中:

require 'spec_helper'

describe Product do

  before(:each) do
    @attr = { 
      :title => "Lorem Ipsum",
      :description => "Wibbling is fun!",
      :image_url => "lorem.jpg",
      :price => 19.99
    }
  end

  it "rejects duplicated titles" do
    Product.create!(@attr)
    product_with_duplicate_title = Product.new(@attr)
    product_with_duplicate_title.should_not be_valid
  end
end

当我运行 rack rspec 时,我得到了:

Failures:

  1) Product should reject if the title is duplicated
     Failure/Error: product_with_duplicate_title.should_not be_valid
       expected valid? to return false, got true
     # ./spec/models/product_spec.rb:26:in `block (2 levels) in <top (required)>

为什么?我也使用 factory_girl 进行了类似的尝试,并得到了相同的结果……其他测试(此处未包括)用于测试空白、有效图像文件名等,都有效。

提前感谢。

【问题讨论】:

    标签: ruby-on-rails rspec2


    【解决方案1】:

    您最好采用更简单的方法:将 shoulda 匹配器与 Rspec 一起使用。你最终只会写:

    describe Product do
      it { should validate_uniqueness_of(:title) }
    end
    

    Doc here.

    【讨论】:

    • 我还建议使用某种工厂来生成值,请参阅rubygems.org/search?utf8=✓&query=factory。我使用 Fabricator,但有很多(我认为 Factory Girl 是使用最广泛的)
    • 虽然通过使用另一个额外的 gem 应该可以帮助解决问题,但它仍然不能帮助我理解我做错了什么。还是谢谢你。
    • 莱恩。谢谢。我确实用 Factory_girl 尝试过同样的事情并得到了同样的错误。
    • 我怀疑be_valid,因为它不再出现在文档中:relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/… 你试过product_with_duplicate_title.valid?.should be_false
    【解决方案2】:

    您的问题看起来有效,我不明白为什么它不起作用。我注意到您仍在使用 Rails 3 中已弃用的旧 Rails 2.x 语法。这应该不是问题,我认为 Rails 3.1 仍然支持该语法。

    我会这样写类似的东西:

    class Product < ActiveRecord::Base
      validates :title, :presence => true, :uniqueness => true
    end
    

    使用上面 Iain 提到的 FactoryGirl。

    let(:product) { FactoryGirl.build(:product) }    
    
    it "has a unique title" do
      older_product = FactoryGirl.create(:product)
      product.title = older_product.title
      product.should_not be_valid
    end
    

    您可以尝试打印出错误吗?也许它不是在标题唯一性上失败了,而是在其他领域失败了?

    【讨论】:

    • 我可能会建议create! 而不是create。我有一个案例,由于验证错误,我的“重复”实际上没有保存,所以看起来我的唯一性验证被破坏了,即使它没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    相关资源
    最近更新 更多