Skilldrick
Skilldrick

Reputation: 70819

How to deal with mocking nested resources in RSpec and Rails?

I've got a nested resource of User Reading Lists (a User has_many Reading Lists). I'm trying to mock everything in my controller specs, but having trouble keeping it concise. Here's the before code for the #show action:

@reading_lists = mock("Reading lists")
@reading_lists.stub!(:find).with("1").and_return(@reading_list)
@user = mock_model(User, :reading_lists => @reading_lists)
User.stub!(:find).with("1").and_return(@user)
get :show, :user_id => "1", :id => "1"

which is testing:

def show
  @user = User.find(params[:user_id])
  @reading_list = @user.reading_lists.find params[:id]
end

This seems like a crazy amount of boilerplate - is there a better way to mock it out?

Upvotes: 3

Views: 945

Answers (1)

David Chelimsky
David Chelimsky

Reputation: 9000

There is not a better way to mock it out, but you are right to note that this is a lot of boiler plate. The reason is that user.reading_lists.find is a Law of Demeter violation. Whether or not you view the Law of Demeter as important, mocking through violations of it is painful.

I'd recommend either using the real models or simplifying the interaction with the model. I can't really say how without seeing what you're trying to specify.

Upvotes: 4

Related Questions