Problems with testing nested routes using mocking

Hello forum

I have there to files

#----- virtual_host_controller.rb
class VirtualHostsController < ApplicationController
before_filter :capture_domain

GET /domain/1/virtual_hosts/1

def show
@virtual_host = @domain.virtual_hosts.find(params[:id])

respond_to do |format|
  format.html # show.rhtml
end

end

private

def capture_domain
if params[:domain_id].blank?
flash[:notice] = ‘Need domain.’
redirect_to domains_url
else
@domain = Domain.find(params[:domain_id])
end
end
end
#----

and

#----- virtual_host_controller_spec.rb
describe VirtualHostsController, “handling GET
/domains/1/virtual_hosts/1” do

before do
@domain = mock_model(Domain)
@virtual_hosts = mock(“virtual_hosts”)
@virtual_host = mock(“virtual_host”)
Domain.should_receive(:find).with(“1”).and_return(@domain)
@domain.should_receive(:virtual_hosts).and_return(@virtual_hosts)
@virtual_hosts.should_receive(:find).and_return(@virtual_host)
login_as :admin
end

def do_get
get :show, :id => “1”, :domain_id => “1”
end

it “should render show template” do
do_get
response.should render_template(‘show’)
end

it “should find the virtual_host requested” do

@domain.should_receive(:virtual_hosts).and_return(@virtual_hosts)

 @virtual_hosts.should_receive(:find).with('1').and_return(@virtual_host)
 do_get

end

it “should assign the found virtual_host for the view” do
do_get
assigns[:virtual_host].should equal(@virtual_host)
end
#-----

I have a problem with these three it should-cases. How can I make them
to work.

The error is:
should find the virtual_host requested
Mock ‘virtual_hosts’ expected :find with (“1”) once, but received it 0
times

The routes are like this:
map.resources :domains do |domains|
domains.resources :virtual_hosts
end

What can I do?

Jesper Laursen wrote:

@virtual_host = @domain.virtual_hosts.find(params[:id])
  flash[:notice] = 'Need domain.'

 login_as :admin

#-----
end

What can I do?


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Correct me if I am wrong, but in the “before do”

@virtual_hosts.should_receive(:find).and_return(@virtual_host)

should be

VirtualHosts.should_receive(:find).and_return(@virtual_host)

Since you are calling find on the class?

Jesper Laursen wrote:

before_filter :capture_domain
private
#----
@virtual_host = mock(“virtual_host”)
it “should render show template” do
it “should assign the found virtual_host for the view” do

Spec::Mocks::MockExpectationError in 'VirtualHostsController handling

So maybe you are a bit wrong :slight_smile:
I found this page,
http://www.vaporbase.com/postings/Rspec_example_for_nested_resource_index_action,
but unfortunately, does he not describe the same things as I am.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

You are correct, it should be

VirtualHost.should_receive(:find).and_return(@virtual_host)

The first, third and fourth errors might be showing up because it should
be the same in the

it “should find the virtual_host requested”

block as well. This is because the object called @virtual_hosts does
not have a method called “find” defined.

2007/10/1, Ryan T. [email protected]:

class VirtualHostsController < ApplicationController

end
@virtual_hosts = mock(“virtual_hosts”)

Mock ‘virtual_hosts’ expected :find with (“1”) once, but received it 0 times
http://rubyforge.org/mailman/listinfo/rspec-users
Since you are calling find on the class?

Mock ‘virtual_hosts’ received unexpected message :find with (“1”)
You are correct, it should be
not have a method called “find” defined.
Okay, now it seems til work.
The problem has what I have to place:
@domain.virtual_hosts.should_receive(:find).with(“1”).and_return(@virtual_host)
in the before, because the “do_get” method was using it, in all
it-blocks.

I just think that my before are pretty big.
And I have to copy it for every describtion.

But thanks a lot. It works OK.

On 1.10.2007, at 18.25, Jesper Laursen wrote:

Okay, now it seems til work.
The problem has what I have to place:
@domain.virtual_hosts.should_receive(:find).with
(“1”).and_return(@virtual_host)
in the before, because the “do_get” method was using it, in all it-
blocks.

I just think that my before are pretty big.
And I have to copy it for every describtion.

You could wrap it in a helper method in a module that you can include
and call in the specs instead of repeating all the lines.

//jarkko


Jarkko L.

http://www.railsecommerce.com
http://odesign.fi

2007/10/1, Jarkko L. [email protected]:

You could wrap it in a helper method in a module that you can include
and call in the specs instead of repeating all the lines.

Yes, I know, but not all the code have to be used every time.
Now I have a new problem. It know work in a browser, but if i am
running autotest, this error raise:

/opt/local/bin/ruby -S script/spec -O spec/spec.opts spec/views/virtual_hosts/show.rhtml_spec.rb F

ActionView::TemplateError in ‘/virtual_hosts/show.rhtml should render
attributes in


edit_virtual_host_url failed to generate from
{:controller=>“virtual_hosts”, :domain_id=>“1001”, :action=>“edit”},
expected: {:controller=>“virtual_hosts”, :action=>“edit”}, diff:
{:domain_id=>“1001”}
On line #92 of app/views/virtual_hosts/show.rhtml

89: </p>
90:
91:
92: <%= link_to 'Edit', edit_virtual_host_path(@virtual_host) %> |
93: <%= link_to 'Back', virtual_hosts_path %>

my before do in show.rhtml_sprec.rb looks like this

before do
@domain = mock_model(Domain)
@domain.stub!(:domain_id).and_return(“1”)

@virtual_host = mock_model(VirtualHost)
@virtual_host.stub!(:servername).and_return("MyString")

assigns[:domains] = @domain
assigns[:virtual_host] = @virtual_host

end

2007/9/30, Ryan T. [email protected]:

def show
if params[:domain_id].blank?

 @virtual_hosts.should_receive(:find).and_return(@virtual_host)

end
end
domains.resources :virtual_hosts
@virtual_hosts.should_receive(:find).and_return(@virtual_host)

should be

VirtualHosts.should_receive(:find).and_return(@virtual_host)

Since you are calling find on the class?

If I change it to VirtualHost (an ‘s’ there, give no sense), these
errors raises:

Spec::Mocks::MockExpectationError in ‘VirtualHostsController handling
GET /domains/1/virtual_hosts/1 should assign the found virtual_host
for the view’
Mock ‘virtual_hosts’ received unexpected message :find with (“1”)

Spec::Mocks::MockExpectationError in ‘VirtualHostsController handling
GET /domains/1/virtual_hosts/1 should find the virtual_host requested’
Mock ‘Class’ expected :find with (any args) once, but received it 0
times

Spec::Mocks::MockExpectationError in ‘VirtualHostsController handling
GET /domains/1/virtual_hosts/1 should render show template’
Mock ‘virtual_hosts’ received unexpected message :find with (“1”)

Spec::Mocks::MockExpectationError in ‘VirtualHostsController handling
GET /domains/1/virtual_hosts/1 should be successful’
Mock ‘virtual_hosts’ received unexpected message :find with (“1”)

So maybe you are a bit wrong :slight_smile:
I found this page,
http://www.vaporbase.com/postings/Rspec_example_for_nested_resource_index_action,
but unfortunately, does he not describe the same things as I am.

On 2.10.2007, at 1.33, Jesper Laursen wrote:

attributes in


edit_virtual_host_url failed to generate from
{:controller=>“virtual_hosts”, :domain_id=>“1001”, :action=>“edit”},
expected: {:controller=>“virtual_hosts”, :action=>“edit”}, diff:
{:domain_id=>“1001”}
On line #92 of app/views/virtual_hosts/show.rhtml

89: </p>
90:
91:
92: <%= link_to 'Edit', edit_virtual_host_path(@virtual_host) %> |

I’ve stumbled upon something similar. I’m using Globalize and setting
the language parameter in a path_prefix: /en/users/1, etc. Rails
itself can pass the language parameter to the REST routes
automatically, so I can just say user_path(@user). However, all the
view specs bomb just like they do here, and I’m forced to say
user_path(:language_id => “en”, :id => @user) just to make the specs
pass, which is both laborious, error-prone and ugly.

//jarkko


Jarkko L.

http://www.railsecommerce.com
http://odesign.fi

On 10/2/07, Jarkko L. [email protected] wrote:

ActionView::TemplateError in '/virtual_hosts/show.rhtml should render
92: <%= link_to ‘Edit’, edit_virtual_host_path(@virtual_host) %> |

I’ve stumbled upon something similar. I’m using Globalize and setting
the language parameter in a path_prefix: /en/users/1, etc. Rails
itself can pass the language parameter to the REST routes
automatically, so I can just say user_path(@user). However, all the
view specs bomb just like they do here, and I’m forced to say
user_path(:language_id => “en”, :id => @user) just to make the specs
pass, which is both laborious, error-prone and ugly.

This is a known issue:

http://rubyforge.org/tracker/index.php?func=detail&aid=12963&group_id=797&atid=3149

Patches welcome!

On 10/2/07, David C. [email protected] wrote:

This is a known issue:

http://rubyforge.org/tracker/index.php?func=detail&aid=12963&group_id=797&atid=3149

Patches welcome!

Not sure if that’s related to the problem I’m having with view specs and
the
dynamic path-generators, but it may be. I tried to run the NetBeans
debugger on my spec, but as far as I can see, it can’t introspect into
the
generated code that routing.rb write_generation performs, which makes it
difficult to diagnose the problem.

I can dig into routing.rb:423 and the calls beneath it, but when I get
to
routing.rb:424, step into just goes away and drops me off at a failed
test.

Does anyone have suggestions for an alternate debugging technique, short
of
modifying rails code, which is a little more intensive than I’d like
right
now? I don’t mind trying to diagnose the problem and, if once
diagnosed,
look into the effort of creating a patch, but at the moment, I don’t
even
know why my route generation’s failing.

  • Geoffrey