Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocking a method exactly should not prevent the method from being called with other arguments #11

Open
lawrencepit opened this issue Sep 3, 2009 · 5 comments
Labels

Comments

@lawrencepit
Copy link

Using rails 2.3.3 and rspec 1.2.6, my view is simply this:

  = render :partial => "layouts/resources"

My rspec test looks like this:

  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')

  describe "/holidays/index.html.haml" do
    it "should render the resources layout partial" do
      # RSpec: works
      #template.should_receive(:render).with(:partial => "layouts/resources")

      # Mocha: fails
      #template.expects(:render).with(:partial => "layouts/resources")

      # RR: fails
      mock(template).render(:partial => "layouts/resources")

      render "/holidays/index.html.haml"
    end
  end

Which results in:

    On subject #<ActionView::Base:0x304b4bc>,
    unexpected method invocation:
      render({:locals=>{}, :layout=>nil, :file=>"holidays/index.html.haml"})
    expected invocations:
    - render({:partial=>"layouts/resources"})

Any advice?

@btakita
Copy link
Owner

btakita commented Oct 19, 2009

It looks like there are multiple calls to render.

Try:
stub(template).render.verbose
mock(template).render(:partial => "layouts/resources")

@lawrencepit
Copy link
Author

The output I get is then:

    render({:layout=>nil, :file=>"holidays/index.html.haml", :locals=>{}})

    should render the resources layout partial
    render({:partial=>"layouts/resources"})
    Called 0 times.
    Expected 1 times.

@thedeeno
Copy link

I can confirm this behavior in rr 0.10.11, rails 2.3.5, rspec 1.3

There is def, as you suggested, a double call to render. This is expected - first the parent view starts rendering, then the child (or partial) view renders. 2 calls to template.render

Rspec mocks can handle this scenario just fine (as noted by OP). Even more confusing is the fact that most examples in the readme deal with the 'doubling' of render(:partial) yet I can't get this to work in view specs at all. Thoughts on how we can set rr up to do this? Any work around? I've tried numerous combinations/setups with no luck.

Regardless thanks for the cool framework. I'm really hoping to switch to this syntax. It's so nice.

@thedeeno
Copy link

I dove into the source and found a solution to this. You can write the test as follows:

mock.proxy(template).render(anything).any_number_of_times
render
template.should have_received({:partial => "layouts/resources"})

I was hoping to be able to use spies (since they seem more appropriate here) but there is a catch the following passes ok but when it's intentionally broken rspec hangs.

spy(template)
render
template.should have_received.render({:partial => 'layouts/resources'})

I'll open a new issue to get to the bottom of that one.

@mcmire
Copy link
Collaborator

mcmire commented Mar 14, 2013

I'll go ahead and mark this as a feature. If you mock a method exactly then it should not prevent the method from being called with other arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants