Search code examples
rspecmockingrspec-railsstubbing

Rspec testing ordered retrieval from a scoped method of model using mocking and expectations


I'm a newb to rspec, mocking and stubbing. I'm slowly starting to appreciate and wrap my head around the concepts of isolated testing and mocking/stubbing in general. I have a basic question, which i think is easier explained through code:

class NewsItem < ActiveRecord::Base
  ...
  scope :ordered, order("created_at DESC")
  ...
end

In my model tests now, I wish to test the behavior that returns an ordered list of news_items. Using FactoryGirl DB-touching testing, I achieve this as follows:

# TODO use mocking and stubbing here
it "should have an ordered method to retrieve news items in the descending order" do
  news_item_x = create(:news_item, created_at: DateTime.new(2012,01,01))
  news_item_y= create(:news_item, created_at: DateTime.new(2011,01,01))
  news_item_z= create(:news_item, created_at: DateTime.new(2012,03,01))

  # .all added to avoid comparison failure between groups of NewsItem objects an ActiveRel group.
  expect(NewsItem.ordered.all).to eql([news_item_z, news_item_x, news_item_y])
end 

I'm at a loss to understand how one would convert the above tests to mocking and stubbing. Here's a first attempt, but clearly i'm misunderstanding some core concept here.

xit "should have an ordered method to retrieve news items in the descending order" do

  news_item_x = mock(NewsItem, created_at: DateTime.new(2012,01,01))
  news_item_y = mock(NewsItem, created_at: DateTime.new(2011,01,01))
  news_item_z = mock(NewsItem, created_at: DateTime.new(2012,03,01))

  NewsItem.should_receive(:ordered).and_return([news_item_z, news_item_x, news_item_y])
  # NewsItem.should_receive(:ordered).ordered # not working.

  # this is pointless as it's not checking the order of anything, just the call.
  NewsItem.ordered
end 

Is mocking/stubbing even appropriate in this kind of a test?

Any advice would be much appreciated.

VERDICT:

I got some great answers from both @arieljuod and @zetetic. To my original question, is mocking and stubbing appropriate here? The answer seems to be No as @zetetic has pointed out.

On the other hand @arieljuod gave a really nice way of actually testing my code snippet (not necessarily through mocking and stubbing). Both of these are valid answers.


Solution

  • Is mocking/stubbing even appropriate in this kind of a test?

    No.

    The point of using mocks and stubs is to isolate code that you write from its dependencies. In the case of scope, everything it depends on is buried in the Rails framework. Also, you shouldn't need to test the internals of framework/library code in the first place -- the original authors have already done that.