[rspec-users] I'm really bad at controllers, help please.

David Chelimsky dchelimsky at gmail.com
Sun Jun 3 09:02:37 EDT 2007


On 6/2/07, Jonathan Linowes <jonathan at parkerhill.com> wrote:
> fyi, i'm finding the should_receive(:messages) to be too brittle
> because any time I add a call like @user.messages.find or whatever it
> breaks my spec (requiring I do .twice or .times(N) . IMO the spec
> shouldn't be so sensitive to implementation of the behavior, so i'm
> now stubbing the association
>
> replaced
>         @user.should_receive(:messages).and_return(@messages)
> with
>         @user.stub!(:messages).and_return(@messages)


FYI - this:

  @user.stub!(:messages).and_return(@messages)

functions in the same way as this:

  @user.should_receive(:messages).any_number_of_times.and_return(@messages)

So you can alleviate the brittleness using should_receive. It's more
verbose, BUT, the important thing is your intention. Stubs and mocks
mean different things.

http://blog.davidchelimsky.net/articles/2006/11/09/tutorial-rspec-stubs-and-mocks

Cheers,
David

>
>
>
> On Jun 2, 2007, at 3:09 PM, Jonathan Linowes wrote:
>
> > I'm nearly as new at this as you are I'm I'm just figuring things out
> > myself too.
> >
> > I think your problem is method :messages is being called on an
> > instance of User, not the class, so you need
> >
> > @user.stub!(:messages).and_return([@message])
> >
> > here's some clues to how I've gotten similar things working
> > To diagnose problems with my examples, I
> > - watch the test.log file. You could use 'tail' or on mac use the
> > 'console' utility
> > - use the -e option in spec to run one example at a time. I copy/
> > paste the test name from the terminal window to avoid a lot of typing
> > - sometimes I comment out code in my app methods to limit what its
> > actually doing and then add one line at a time to "re-develop" the
> > method
> > - similarly I may create an extra test method in my controller or
> > model to isolate things I dont understand between the spec and the
> > code.
> >
> > I also tend to use should_receive rather than stubs, it provides more
> > details (although seems to make the tests more brittle)
> >
> > thus,
> >
> > # separate for reuse with multiple describe cases
> > def setup_messages do
> >    @user = mock_model(User)
> >    @message = mock_model(Message)
> >    @messages = [@message]
> > end
> >
> > def before(:each) do
> >    setup_messages
> >    User.should_receive(:find).with("1").and_return(@user)
> >    @user.should_receive(:messages).and_return(@messages)
> > end
> >
> > def do_get
> >    get :index, :user_id => 1
> > end
> >
> > it "should find all messages" do
> >    do_get
> >    assigns[:messages].should == @messages
> > end
> >
> > I think this is right. Please let me know
> > :)
> >
> >
> > On Jun 2, 2007, at 4:27 AM, Fischer, Daniel wrote:
> >
> >> Hey,
> >>
> >> Sorry for so many questions - I'm really bad at this right now.
> >>
> >> I'm trying to cover the following code w/ rspec
> >>
> >>   def index
> >>     if params[:user_id]
> >>       @user = User.find(params[:user_id])
> >>       @messages = @user.messages
> >>     end
> >>   end
> >>
> >> So basically what I'm doing is listing all the messages for a user,
> >> provided there is an id parameter.
> >>
> >> describe MessagesController, " handling GET /messages for a user" do
> >>
> >>   before do
> >>     @message = mock_model(Message)
> >>     @message.stub!(:user_id).and_return(1)
> >>     @user = mock_model(User)
> >>     @user.stub!(:id).and_return(1)
> >>     User.stub!(:messages).and_return([@message])
> >>     User.stub!(:find).and_return([@user])
> >>   end
> >>
> >>   def do_get
> >>     get :index, :user_id => 1
> >>   end
> >>
> >>   it "should be successful" do
> >>     do_get
> >>     response.should be_success
> >>   end
> >>
> >>   it "should render index template" do
> >>     do_get
> >>     response.should render_template('index')
> >>   end
> >>
> >>   it "should find all messages" do
> >>     User.should_receive(:messages).and_return([@message])
> >>     do_get
> >>   end
> >>
> >>   it "should assign the found messages for the view" do
> >>     do_get
> >>     assigns[:messages].should == [@message]
> >>   end
> >> end
> >>
> >>
> >> I'm trying to use the basic scaffold spec, but I'm absolutely
> >> clueless
> >> on what the proper way to handle this is, I'm not even sure the
> >> proper
> >> way I should mock the messages method, so it'll return a "stub?" of a
> >> collection, or whatever the proper term is.
> >>
> >> I'm sorry you have to deal with a newb, but if you could really help
> >> me out I'd appreciate it a ton, thanks!
> >> --
> >> -Daniel Fischer
> >> _______________________________________________
> >> rspec-users mailing list
> >> rspec-users at rubyforge.org
> >> http://rubyforge.org/mailman/listinfo/rspec-users
> >
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list