Item model spec file

I have this requirement

Item

An item must have a title, description, and price.
The title and description cannot be empty strings.
The title must be unique for all items in the system
The price must be a valid decimal numeric value and greater than zero
The photo is optional. If present it must be a valid URL format.

Are the following specs fine? And what i write for the last url format?

require 'spec_helper'

describe Item do

	before do
		@item =  Item.new(title:"This has a description",description:"This has a title")
	end

	it "item should be valid if title and description are present" do
    expect(@item).should be_valid
	end
	it { should respond_to(:title) }
	it { should respond_to(:description) }
  it { should respond_to(:price) }
  it { should respond_to(:photo) }
  it { should validate_numericality_of(:price) }
  it { should validate_uniqueness_of(:title)}
  it { should validate_numericality_of(:price).is_greater_than(0) }

  it "title cannot be empty" do
    item = Item.new(title:"",description:"This has no title")
    expect(item).to_not be_valid
  end

  it "description cannot be empty" do
    item = Item.new(description:"",title:"This has no description")
    expect(item).to_not be_valid
  end

  it "The price must greater than zero" do
    item = Item.new(description:"This should not be valid",title:"Valid numeric but value less than 0",price: -20)
    expect(item).to_not be_valid
  end

  it "The price must be valid numeric value" do
    item = Item.new(description:"This should not be valid",title:"Valid numeric but value less than 0",price: -20)
    expect(item).to_not be_valid
  end

 it "The photo is optional. If present it must be a valid URL format." do

  end
end

It seems like you are duplicating a lot of tests. Using shoulda matchers is great because it takes care of the common data validations. I don’t think you need to go in and add examples for each one of those. You’ve already tested those!

You can use shoulda’s validate_presence_of matcher, instead of the tests you wrote for that.

Also, there is no reason for the before block, especially because you’re only using the @item in one test. Move it to a local variable on the test.

Also, since you’re using RSpec’s expect syntax, you can write expect(item).to be_valid, which reads better.

1 Like