[rspec-users] [newbie]: How to test for operations inside a block?

Mark Wilden mark at mwilden.com
Mon Sep 22 14:18:33 EDT 2008


On Mon, Sep 22, 2008 at 9:07 AM, Carmine Moleti <lists at ruby-forum.com>wrote:

>
>  def create
>    authenticate_with_open_id(params[:identity_url], :required => [
> :nickname, :email ], :optional => :fullname) do |result, identity_url,
> registration|
>      if result.successful?
>        @user = User.new
>        @user.identity_url = identity_url
>        @user.roles << Role.find_by_name('operator')
>        @user.user_type = 'operator'
>        assign_registration_attributes!(registration)
>        @user.save(false)
>        redirect_to users_path
>      else
>        redirect_to new_user_path
>      end
>    end
>  end
>

In general, the mantra is "skinny controllers, fat models," meaning that if
you can put code in the model, you probably should. For no other reason,
because it makes testing easier and faster. Controllers should (again, in
general) act as dispatchers to the code that really does the work: the
models to handle the logic, and the views to handle the presentation.
Searching on the mantra above will probably explain this more fully.

In this case, it appears to me that you're creating a new user based on some
OpenID information. There's nothing in that code that's specific to POSTing
certain information to a certain URL in your app, which is what controllers
handle. How a User gets created from OpenID information is really the User
class's responsibility, in my opinion. It's business logic, and you like to
keep business logic as close as possible to its object. While we don't
generally like to program for the future, it's easy to see that if business
logic is spread over controllers as well as models, it's going to be harder
to debug, maintain, etc.

  it "should create a new user using OpenID authentication" do

>     @controller.stub!(:authenticate_with_open_id)
>     @user = new_user # thanks to fixture_replacement2
>     User.stub!(:new).and_return(@user)
>     @user.should_receive(:save).with(false).and_return(true)
>     do_verb
>   end
>
> The first test pass successfully while the second throws havocs on me.
> It complains on the "@user.should_receive(:save..." part.
> It also complained when I wrote
> "User.should_receive(:new).and_return(@user)", so I changed
> it to "User.stub!(:new)...". But I don't fully understand why I had to
> do so.
>

It looks like you want to use something like
@controller.should_receive(:authenticate_with_open_id).and_yield(<etc>)

I didn't know about and_yield() before. Cool!

///ark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080922/ded3a188/attachment-0001.html>


More information about the rspec-users mailing list