2

I don't want rspec to let me save two objects of the class with the same name, however it does. Is there something I'm missing?

My model:

class Product < ActiveRecord::Base
  validates :title, :description, :image_url, presence: true
  validates :price, numericality: {greater_than_or_equal_to: 0.01}
  validates :title, uniqueness: true
  validates :image_url, allow_blank: true, format: {
    with: %r{\.(gif|jpg|png)\Z}i,
    message: 'must be a URL for GIF, JPG or PNG image'
  }
end

my test:

describe "when creating products with identical names" do
    let(:book1) { FactoryGirl.create(:product, title: 'identical') }
    let(:book2) { FactoryGirl.build(:product, title: 'identical') }

    it "raises unique validation error" do
        expect(book2).not_to be_valid
    end
end

this is what I get:

1) Product when creating products with identical names raises unique validation error
     Failure/Error: expect(book2).not_to be_valid
       expected #<Product id: nil, title: "identical", description: "Some crazy wibbles, that are fun", image_url: "freddie_mercury.jpg", price: #<BigDecimal:7f995cdd1358,'0.5699E2',18(27)>, created_at: nil, updated_at: nil> not to be valid

I can even write two times FactoryGirl.create, it just saves.

However if I switch over to rails console and try to create two objects with two identical names, I receive an error. Something wrong with my testing environment?

mohnstrudel
  • 639
  • 8
  • 22

1 Answers1

2

Well, the book1 is not created in your test run... consider changing:

describe "when creating products with identical names" do
  let(:book1) { FactoryGirl.create(:product, title: 'identical') }
  let(:book2) { FactoryGirl.build(:product, title: 'identical') }

  it "raises unique validation error" do
    expect(book2).not_to be_valid
  end
end

to

describe "when creating products with identical names" do
  let(:book) { FactoryGirl.build(:product, title: 'identical') }

  before do
    FactoryGirl.create(:product, title: 'identical')
  end

  it "raises unique validation error" do
    expect(book).not_to be_valid
  end
end

This should help! Good luck!

Paweł Dawczak
  • 9,519
  • 2
  • 24
  • 37
  • 1
    thank you! Do I understand it correctly, that a let() - block doesn't essentially perform the action inside the block? So basically in book1 I just saved an action instead of performing that action? – mohnstrudel Mar 30 '15 at 12:17
  • Actually, what `let` does you can imagine as a "registering" a method of the name specified as symbol, so `let(:book1) { ... }` makes possible to call `book1` in your tests. Until you call the method, the body of the block is not executed. You could check it, if in your original code you performed something like `before { book1 }`, or in your `it` block just called `book1` before `expect(book2).not_to be_valid`. However none of them seems readable. – Paweł Dawczak Mar 30 '15 at 12:22