[rspec-users] proxy associantion on controllers

Daniel Lopes danielvlopes at gmail.com
Fri Dec 5 15:19:07 EST 2008


Thanks a lot Nick...
No, i'm not using Authlogic because already have base project with
restful_authentication implemented with activation, roles and etc... and
when I look authlogic the project was young, I don't know now.

About Martin Fowler post, I already readed... but the problem is because I
know the diference between mocks and stubs ( mocks really call the method
and it fail return a error, and stubs only return the result without check
real method, right? ) but I don't know how use it in RSpec...

I'm starting understand now in this post ( my idea is copy this thread and
translate to portuguese to help more people)... My doubt about mock and
stubs is when I write this:

@user = mock_model User => create mock object based on User and put in
@user.

but when I write the code below, the method User.name will not be called in
this moment, but will be called when User class try to call name and will
return 'Bob' no matter what the real name method does... is this?
@user.stub!(:name).and_return('Bob')


About my previous code... I mocked User in instance variable @user but I
have will_paginate installed and this bring a strange error when I try:
@user.sohuld_receive(:properties).and_return([mock_property])

The error is:

1)
NoMethodError in 'PropertiesController responding to GET index should expose
all properties of given user as @properties'
undefined method `find' for #<Class:0x23a0f64>
/Users/daniellopes/Trabalhos/luvima/luvima/vendor/gems/mislav-will_paginate-2.3.6/lib/will_paginate/finder.rb:167:in
`method_missing'
/Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:61:in
`load_user'
./spec/controllers/properties_controller_spec.rb:20:
spec/controllers/sessions_controller_spec.rb:102:

My spec code is:

describe PropertiesController do

  def mock_property(stubs={})
    @mock_property ||= mock_model(Property, stubs)
  end

  before :each do
    @current_user = mock_model(User, :id => 1)
    controller.stub!(:check_administrator_role).and_return(true)
    User.stub!(:find).and_return(@user)
  end

  describe "responding to GET index" do

    it "should expose all properties of given user as @properties" do
      @user.should_receive(:properties).and_return([mock_property])
      get :index
      assigns[:properties].should == [mock_property]
    end

  end


And my controller code where error refer is:

  private
  def load_user
    @user = User.find(params[:user_id])
    if @user.nil?
      flash[:notice] = "Registro n&atilde;o encontrado"
      redirect_to root_path
    end
  end

Atenciosamente,

Daniel Lopes    Area Criações
Design, Websites e Sistemas Web

Visite:  http://www.areacriacoes.com.br/projects
          http://blog.areacriacoes.com.br/

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
55 (31) 3077-4560  /  55 (31) 8808-8748  /  55 (31) 8737-7501


On Fri, Dec 5, 2008 at 3:55 PM, Nick Hoffman <nick at deadorange.com> wrote:

> On 2008-12-05, at 10:06, Daniel Lopes wrote:
>
>> Thanks for help and sorry for insistance but I don't understand aspects on
>> rspec ( I think not understand how we use mocks and stubs):
>>
>
> Hi Daniel. If you're a bit unsure about when to use mocks vs stubs, have a
> read of this article by Martin Fowler:
> http://martinfowler.com/articles/mocksArentStubs.html
>
> The short version of that article is:
> -You mock objects: @photo = mock_model Photo
> -You stub methods: @photo.stub!(:height).and_return(123)
>
>  The behavior of my controller is...
>> Before Filter:
>> check_administrator_role
>> load_user
>>
>
> Are you using Authlogic?
>
>  So, in this case I want run my before filter methods in before block on
>> rspec, like below:
>>
>
> Nope!  =)  before-filters are called when a controller action is called;
> they aren't called in your specs' "before" blocks.
>
>  describe PropertiesController do
>>  def mock_property(stubs={})
>>    @mock_property ||= mock_model(Property, stubs)
>>  end
>>
>>  before do
>>    @current_user = mock_model(User, :id => 1)  <== define a current_user
>> with id 1
>>    controller.stub!(:check_administrator_role).and_return(true) <== and
>> current_user is administrator
>>    @params = {:user_id=>1}  <== define params
>>    User.stub!(:find).with(@params[:user_id]).and_return(@user) <== and now
>> try fetch the user with id 1
>>  end
>>
>
> Keep in mind that it's
>    before :each do
> or
>    before :all do
>
>   This line will define @user variable, right?
>>  User.stub!(:find).with(@params[:user_id]).and_return(@user)
>>
>
> That line above tells the User class to return @user when #find is called
> on it with the argument @params[:user_id] .
>
> You don't need to create a "params" variable. Eg:
>
> before :each do
>  @user = mock_model User
>  controller.stub!(:check_administrator_role).and_return(true)
>  User.stub!(:find).and_return @user
> end
>
>   But I don't need mock the @user variable to fill it with valid values (
>> like user_id, name, email and etc ) ?
>>
>
> If you want those methods, you'd stub them on @user, like this:
>  @user = mock_model User, :name => 'Bob'
> or like this:
>  @user = mock_model User
>  # ..some other code here..
>  @user.stub!(:name).with(no_args).and_return('Bob')
>
>   describe "responding to GET index" do
>>    it "should expose all properties of given user as @properties" do
>>      @user.should_receive(:properties).and_return([mock_property])
>>      get :index
>>      assigns[:properties].should == [mock_property]
>>    end
>>  end
>>
>
> That looks about right.
> -Nick
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/b5f80e31/attachment-0001.html>


More information about the rspec-users mailing list