1

I have a spec for a model called Item:

describe Item do

  it { should have_db_column :name }
  it { should have_db_column :description }
  it { should have_db_column :price }

  # etc …

  describe '.by_popularity' do

    it "returns all items in order of popularity" do

      @items = 3.times.map { create(:item) }
      2.times.map { create(:order, item: @items[0]) } 
      3.times.map { create(:order, item: @items[1]) } 
      1.times.map { create(:order, item: @items[2]) }

      expect(Item.by_popularity).to eq([@items[1], @items[0], @items[2]])

    end
  end
end

For all the tests preceding the .by_popularity scope, everything works great. RSpec implicitly creates a new Item which is used as the it/subject.

However in the .by_popularity test which is testing scope, I don't want the extra Item that is implicitly created as it crops up in the returned values from the call to Item.by_popularity, causing the assertion to fail.

How can I prevent RSpec creating this implicit model for this specific describe block?

I have tried declaring a subject, setting it to an empty object, setting it to nil etc, but RSpec still creates an Item model.

My current workaround is to call Item.delete_all at the start of the it block but obviously this is not ideal.

Undistraction
  • 42,754
  • 56
  • 195
  • 331

1 Answers1

1

By using a class name as the first argument to describe, RSpec will (lazily) instantiate an instance of that class for every example in your scope, as described in https://www.relishapp.com/rspec/rspec-core/v/3-0/docs/subject/implicitly-defined-subject.

However, it doesn't do anything on its own to persist the instance, so if you have four persisted Items present at the time of your failed expectation, it's due to something else (e.g. pre-existing in your database or created by some previously executed example in your test and not cleaned up).

Peter Alfvin
  • 28,599
  • 8
  • 68
  • 106
  • You are correct. RSpec uses `new`, not `create`. Inexplicably the problem has gone away today, so you might as well get the candy. – Undistraction Jun 21 '14 at 14:31