3

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?

0

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi David, thanks a lot for your answer. Yes, I hadn't thought about it in terms of the Law of Demeter but you're absolutely right. The bit I'm trying to specify is the second code sample - I just want to find a ReadingList that belongs to a specified User (rather than doing User.find). Anyway, I think you're right - I'll just cut out all the stubbing and go with real models. Cheers!
Thinking about this, I think I'd rather go for user.find_reading_list. I might make a plugin that'll add methods like that to models with AR associations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.