Forum: RSpec rspec controller action list

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.
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-02-28 10:54
This action will list all the articles according to city. Please, can
some one guide me through this spec.

def list
  @articles = find_city.articles.paginate :all,  :page => params[:page]
, :order
  => "live_on DESC", :conditions => { :type_for => "blog" }
end


it "should list all articles" do
   get :list
   controller.stub!(:find_city)
   controller.should_receive(:find_city)
   controller.stub!(:articles)
   controller.should_receive(:articles)

    articles.should_receive(:paginate).and_return(@articles)
    response.should render_template('articles/list')
end

I get the following error when I run the spec.

NameError in 'ArticlesController should list all articles'
undefined local variable or method `articles' for
#<Spec::Rails::Example::Contro
llerExampleGroup::Subclass_1:0xa7b57dc>
spec/controllers/articles_controller_spec.rb:212:
spec/controllers/articles_controller_spec.rb:3:
David Chelimsky (Guest)
on 2008-02-28 15:17
(Received via mailing list)
On Thu, Feb 28, 2008 at 3:54 AM, Namrata Tiwari <lists@ruby-forum.com>
wrote:
> This action will list all the articles according to city. Please, can
>  some one guide me through this spec.
>
>  def list
>   @articles = find_city.articles.paginate :all,  :page => params[:page]

This line has what we call a train wreck. Don't be alarmed! It sounds
dramatic, but that's a common term for a series of objects strung
together with dots:

find_city returns the first object, on which articles gets called.
articles returns the second object, on which paginate is called.

As soon as you have that second dot you have a train wreck.

More below ...

>  , :order
>   => "live_on DESC", :conditions => { :type_for => "blog" }
>  end
>
>
>  it "should list all articles" do
>    get :list

Here the action is called before setting up all the expectations. When
using mocks and stubs, they have to be set up before the action.

>    controller.stub!(:find_city)

Because the code has find_city returning an object, the stub has to
return an object. Because the object returned by find_city gets sent
paginate, it must be able to respond to that so it needs to either be
the kind of object (an AssociationProxy) or a substitute.

>    controller.should_receive(:find_city)
>    controller.stub!(:articles)
>    controller.should_receive(:articles)
>
>     articles.should_receive(:paginate).and_return(@articles)
>     response.should render_template('articles/list')
>  end

Given the code above, the spec needs to do this:

articles = mock("articles")
articles.should_receive(:paginate).
  with(order => "live_on DESC", :conditions => { :type_for => "blog" })
controller.should_receive(:find_city).and_return(articles)
get :list

HTH,
David
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-02-29 05:27
Thanks Mr David for your reply. This gives me a better understanding of
so called train wreck. I am still facing problems with this spec.
firstly - I think I need to put a colon before order(e.g. :order=>
"live_on DESC")

#list
  it "should list all articles" do
    articles = mock("articles")
    articles.should_receive(:paginate).with(:order => "live_on DESC",
:conditions => { :type_for => "blog" })
    controller.should_receive(:find_city).and_return(articles)
    get :list
  end


but this gives me the following error
Spec::Mocks::MockExpectationError in 'ArticlesController should list all
article
s'
Mock 'ArticlesController' expected :find_city with (any args) once, but
received
 it 0 times
spec/controllers/articles_controller_spec.rb:3:

Thanks,
Namrata.
Bryan Ray (Guest)
on 2008-02-29 14:53
(Received via mailing list)
It has to do with your "find_city" method. You spec is expecting it to
be
called from controller, hence:

controller.should_receive(:find_city)

Where is that method and why isn't it being called should be your next
questions based on the code and spec you've pasted.

Hope that helps, buddy.

On Thu, Feb 28, 2008 at 10:27 PM, Namrata Tiwari <lists@ruby-forum.com>
wrote:

>    controller.should_receive(:find_city).and_return(articles)
>  it 0 times
>
--
Bryan Ray
http://www.bryanray.net

"Programming today is a race between software engineers striving to
build
bigger and better idiot-proof programs, and the Universe trying to
produce
bigger and better idiots. So far, the Universe is winning."
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-03-03 04:38
Bryan Ray wrote:
> It has to do with your "find_city" method. You spec is expecting it to
> be
> called from controller, hence:
>
> controller.should_receive(:find_city)
>
> Where is that method and why isn't it being called should be your next
> questions based on the code and spec you've pasted.
>

The method find_city is in application controller. I think the method
'find_city' is being called but its expecting some args.

Thanks,
Namrata.
Matthias Hennemeyer (Guest)
on 2008-03-03 11:19
(Received via mailing list)
Am 03.03.2008 um 04:38 schrieb Namrata Tiwari:

> The method find_city is in application controller. I think the method
> 'find_city' is being called but its expecting some args.
>
The message:

Mock 'ArticlesController' expected :find_city with (any args) once, but
received
  it 0 times

means that the method find_city was *not*  called.

If the original method expects args or not doesn't matter.
Because should_receive works as both an expectation and a stub, the
original method will not be called and no ArgumentError will be raised.
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-03-03 12:04
Matthias Hennemeyer wrote:
> Am 03.03.2008 um 04:38 schrieb Namrata Tiwari:
>
>> The method find_city is in application controller. I think the method
>> 'find_city' is being called but its expecting some args.
>>
> The message:
>
> Mock 'ArticlesController' expected :find_city with (any args) once, but
> received
>   it 0 times
>
> means that the method find_city was *not*  called.
>
> If the original method expects args or not doesn't matter.
> Because should_receive works as both an expectation and a stub, the
> original method will not be called and no ArgumentError will be raised.

Okaayyy!
Then can you also please say why its not calling this :find_city method?

Thx,
Namrata.
David Chelimsky (Guest)
on 2008-03-03 12:16
(Received via mailing list)
On Mon, Mar 3, 2008 at 5:04 AM, Namrata Tiwari <lists@ruby-forum.com>
wrote:
>  >   it 0 times
>  >
>  > means that the method find_city was *not*  called.
>  >
>  > If the original method expects args or not doesn't matter.
>  > Because should_receive works as both an expectation and a stub, the
>  > original method will not be called and no ArgumentError will be raised.
>
>  Okaayyy!
>  Then can you also please say why its not calling this :find_city method?

If the code is the same as it was in the first post in this thread,
it's because the action is taking place before setting the
expectations.
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-03-03 12:22
>
> If the code is the same as it was in the first post in this thread,
> it's because the action is taking place before setting the
> expectations.

Yes, it is the same. As you have suggested earlier.
I am pasting the spec again.

#list
  it "should list all articles" do
    articles = mock("articles")
    articles.should_receive(:paginate).with(:order => "live_on DESC",
:conditions => { :type_for => "blog" })
    controller.should_receive(:find_city).and_return(articles)
    response.should be_success
    get :list

  end

Thx,
Namrata.
David Chelimsky (Guest)
on 2008-03-03 12:38
(Received via mailing list)
On Mon, Mar 3, 2008 at 5:22 AM, Namrata Tiwari <lists@ruby-forum.com>
wrote:
>  #list
>   it "should list all articles" do
>     articles = mock("articles")
>     articles.should_receive(:paginate).with(:order => "live_on DESC",
>  :conditions => { :type_for => "blog" })
>     controller.should_receive(:find_city).and_return(articles)
>     response.should be_success
>     get :list
>
>   end

That is NOT the same :) In the initial post the first line was 'get
:list' - now that is the last line. So while you're at it, please post
the action again as well.
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-03-04 06:21
Here is the action -
def list
    @articles = find_city.articles.paginate :all,  :page =>
params[:page] , :order     => "live_on DESC", :conditions => { :type_for
=> "blog" }
end

and the spec -

it "should list all articles 2" do
    articles = mock("articles")
    get :list

    controller.should_receive(:find_city).and_return(articles)
    controller.should_receive(:articles)

    articles.should_receive(:paginate).with(:order => "live_on DESC",
:conditions => { :type_for => "blog" })
    response.should render_template('articles/list')
end


I am stubbing find_city and articles during set up

before_post do
   controller.stub!(:find_city)
   controller.stub!(:articles)
end

Is this right?
David Chelimsky (Guest)
on 2008-03-04 06:39
(Received via mailing list)
On Mon, Mar 3, 2008 at 11:21 PM, Namrata Tiwari <lists@ruby-forum.com>
wrote:
>  it "should list all articles 2" do
>     articles = mock("articles")
>     get :list

Whoa. A couple of posts ago you said the action (get :list) was the
last thing. Now it's not anymore. When dealing with mocks and stubs,
order is very important, which is why I asked you where the action
was. Message expectations (mocks) and stub values MUST be set before
the action.

>     controller.should_receive(:find_city).and_return(articles)

The implementation is find_city.articles, so find_city needs to return
something that owns articles.

>     controller.should_receive(:articles)

This one is just wrong - it's the return value of find_city that
should receive articles.

>     articles.should_receive(:paginate).with(:order => "live_on DESC",
>  :conditions => { :type_for => "blog" })

This one is right, but again, needs to happen before the action.

>
>     response.should render_template('articles/list')

This one is correct, and in the correct place (after the action).

>  end
>
>
>  I am stubbing find_city and articles during set up
>
>  before_post do
>    controller.stub!(:find_city)

Here find_city will not return anything, so it'll blow up on
find_city.articles ....

>    controller.stub!(:articles)
>  end
>
>  Is this right?

Here's what you want: http://pastie.caboo.se/161001

HTH,
David
3dbf28719f8f6eb28282f2dd6e3f8c11?d=identicon&s=25 Namrata T. (namrata)
on 2008-03-04 07:42
Followed your example! Still getting the following error -
Spec::Mocks::MockExpectationError in 'ArticlesController should list all
article
s'
Mock 'ArticlesController' expected :find_city with (any args) once, but
received
 it 0 times
spec/controllers/articles_controller_spec.rb:3:

Thanks,
Namrata
D46dd740e7b242ce769949d9d15bedf2?d=identicon&s=25 Phillip K. (pkoebbe)
on 2008-04-08 13:36
I'm a complete rSpec newbie, so I might be stepping in somewhere that I
don't belong, but...

Namatra, you said earlier that you were stubbing during setup, and you
shared the before_post method.  In the spec, though, you are going a
:get.  I'm not familiar with testing controllers yet (just getting into
that today, in fact), so I don't know if there is a before_get. Could
that be part of your problem:  confusing GETs and POSTs?

Peace,
Phillip
D46dd740e7b242ce769949d9d15bedf2?d=identicon&s=25 Phillip K. (pkoebbe)
on 2008-04-08 13:37
Phillip Koebbe wrote:
>
> Namatra,

Sorry, I spelled your name wrong.

Namrata

Peace,
Phillip
This topic is locked and can not be replied to.