Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing presence and belongs_to with Rspec

I'm trying to learn how to test with Rspec.

At the moment I have a spec for an Item class:

require 'spec_helper'

describe Item do
  it { should belong_to :list }

  before(:each) do
    @item = FactoryGirl.create(:item)
  end

  subject { @item }

  it { should respond_to :name }
  it { should validate_presence_of :name }

end

I have a couple of questions about this , though.

Is it { should validate_presence_of :name } the same as writing:

describe "when name is not present" do
  before { @item.name = "" }
  it { should_not be_valid }
end

or is there a crucial difference between the two?

I was also wondering if it { should belong_to :list } is worth writing in a spec, or if there's a better way for this.

I also know I can do @item = FactoryGirl.build(:item) or FactoryGirl.create(:item). Does create save the item to the test db and build doesn't? Or am I confused here. When should I use which?

Thanks.

like image 755
Joris Ooms Avatar asked Feb 19 '23 13:02

Joris Ooms


1 Answers

I am guessing you are using shoulda-matchers or something similar. They have the advantage (I think) that they offer you short and concise matchers, like you used.

Personally I believe the following tests:

it { should belong_to :list }
it { should validate_presence_of :name }

are important, since most likely my class will look as follows:

class Item
  belongs_to :list
  validate_presence_of :name
end

If somebody changes any of those lines, it will show up in the tests.

So imho they are indeed worthy of writing a spec, and it is not much work either.

Secondly: yes, should validate_presence_of is indeed similar to the larger form, but I find the shorter form much more expressive. Please use the short form!

Thirdly: FactoryGirl differences:

  • use FactoryGirl.create if the object needs to exist in the database, e.g. because you want to test that your controller can retrieve items.
  • use FactoryGirl.build if you only need an object, and it is not required the object exists in the database. Not saving objects to the database will make your tests quicker.

Hope this helps.

like image 105
nathanvda Avatar answered Mar 02 '23 19:03

nathanvda