RSpec 2 testing uniqueness
I know I should be testing validations, but I'm learning so would like to know why my code doesn't work.
Environment Ruby 1.9.2, Rails 3.1, RSpect 2.6.4
I got a Product model:
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 => "mus开发者_开发知识库t 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
in the 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
When I run rack rspec, I got:
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)>
Why? I also tried something similar using factory_girl, and got the same result… other tests (not included here) for testing blanks, valid image file names, etc., all worked.
Thanx in advance.
You'd better follow a far easier path: using shoulda matchers along with Rspec. You'd end up simply writing:
describe Product do
it { should validate_uniqueness_of(:title) }
end
Doc here.
Your question looks valid, I don't understand why it isn't working. I noticed you are still using the old Rails 2.x syntax which was deprecated in Rails 3. That shouldn't be the problem, I think the syntax is still supported in Rails 3.1.
Here is how I would write something similar:
class Product < ActiveRecord::Base
validates :title, :presence => true, :uniqueness => true
end
Using FactoryGirl as Iain mentions above.
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
Can you try to print out the errors? Maybe it isn't failing on the title uniqueness but on some other field?
精彩评论