Forum: RSpec problem to mock association proxy

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
89e57a28dfdb85e07b33f92783dbe349?d=identicon&s=25 Daniel Lopes (Guest)
on 2008-12-05 14:54
(Received via mailing list)
Hello, I'm trying learn Rspec but having problems to understand when and
how
user mocks and stubs.
I have a properties_controller with to before_filter actions
(check_administrator_role e load_user)... to access index action of
properties_controller I need have a params[:user] and this parameter
will be
used to load ther user in method load_user ...

Like bellow:

  before_filter :check_administrator_role
  before_filter :load_user

  # GET /properties
  def index
    @properties = @user.properties
  end

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

But I don't know how test index and load_user without fixtures, take a
look
on my specs:

describe PropertiesController do

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

  before do
    @current_user = mock_model(User, :id => 1)
    controller.stub!(:check_administrator_role).and_return(true)
    @user = mock_model(User, :id=>1)
    controller.stub!(:load_user).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


But I having this error:

NoMethodError in 'PropertiesController responding to GET index should
expose
all properties of given user as @properties'
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.properties
/Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:8:in
`index'
./spec/controllers/properties_controller_spec.rb:21:

So, how is the right way to mock associated records?

Thanks.


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
2ce9c0106b5851b2294ba5eb9f5c04bd?d=identicon&s=25 Ashley Moran (Guest)
on 2008-12-05 21:18
(Received via mailing list)
On 5 Dec 2008, at 13:42, Daniel Lopes wrote:

> NoMethodError in 'PropertiesController responding to GET index
> should expose all properties of given user as @properties'
> You have a nil object when you didn't expect it!
> The error occurred while evaluating nil.properties
> /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/
> properties_controller.rb:8:in `index'
> ./spec/controllers/properties_controller_spec.rb:21:
>
> So, how is the right way to mock associated records?

Hi Daniel

The error you are seeing is because the assignment to @user happens
inside #load_user: the live code never call` `@user = load_user`.  As
far as possible, you want to avoid modifying objects under test -
private methods are only the business of instances of that class.
It's much safer in this case to do

   User.should_receive(:find).and_return(@user)

That way, the filter will run as normal.

As for the association - it's actually irrelevant what that returns.
All you care is that whatever comes out of `@user.properties` is
assingned to the view.  I tend to use symbols to represent objects
(including arrays) that get passed around.  For example:

describe PropertiesController do

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

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

   describe "responding to GET index" do
     it "should expose all properties of given user as @properties" do
       get :index
       assigns[:properties].should == :user_properties
     end
   end

end

HTH

Ashley

--
http://www.patchspace.co.uk/
http://aviewfromafar.net/
Fee80fad857baeb14ff106d71eab5332?d=identicon&s=25 Daniel Area Criações (Guest)
on 2008-12-05 21:28
(Received via mailing list)
Thanks Ashley, now the tests passed... but I want understand one thing:
This line is only saying that @properties (assigned[:properties]) have
some
value ... is that?
assigns[:properties].should == :user_properties

I can change above to assigns[:properties].should_not be_nill and the
semantic value will be the same, right?

Thanks...

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 6:16 PM, Ashley Moran
2ce9c0106b5851b2294ba5eb9f5c04bd?d=identicon&s=25 Ashley Moran (Guest)
on 2008-12-05 21:43
(Received via mailing list)
On 5 Dec 2008, at 20:26, Daniel Area Criações wrote:

> This line is only saying that @properties (assigned[:properties])
> have some value ... is that?
> assigns[:properties].should == :user_properties
>
> I can change above to assigns[:properties].should_not be_nill and
> the semantic value will be the same, right?


Ah no, the semantic value is different because this would also pass:

   def index
     @properties = "vegetable soup"
   end

Yet that does not implement the same behaviour.

When you write a behaviour example, always ask the question "What
could I realistically write that could pass this but not give the
desired behaviour?"  That way you will avoid false confidence in specs
where the behaviour could be broken in the future (perhaps during
refactoring), but RSpec still reports success.

Ashley

--
http://www.patchspace.co.uk/
http://aviewfromafar.net/
Fee80fad857baeb14ff106d71eab5332?d=identicon&s=25 Daniel Area Criações (Guest)
on 2008-12-05 21:53
(Received via mailing list)
Thanks Ashley, you right.
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 6:41 PM, Ashley Moran
This topic is locked and can not be replied to.