Forum: RSpec should_receive not receiving on a returned instance variable

Posted by lawwantsin (Guest)
on 2010-02-26 04:43
(Received via mailing list)
i'm calling a very simple should_receive method on a returned instance
and it's saying the implementation code is not calling it.  i get this
error in my specs alot.  i've read the rspec beta book and it doesn't
mention examples like this.  i couldn't find any solutions on the
forum yet so i wanted to reach out.  it seems like i'm just not
getting something about the rspec api.

==SPEC==

   before :all do
     @scene =  Factory.create(:scene)
     @project = Project.create(:working_title => "test")
     @project.scenes << [@scene]
     @project.save
  end

    it 'should call done! on @scene' do
      @project.stub_chain(:scenes, :find).and_return(@scene)
      @scene.should_receive(:done!).and_return(true)
        xhr :post, :done, {:id => @scene.id, :project_id =>
@project.id}
    end

==IMPLEMENTATION==
class ScenesController < ApplicationController

 before_filter :get_project

 def done
    @scene = @project.scenes.find(params[:id])
    if @scene.done!
      render
    else
      render_alert("Scene cannot be marked done.")
    end
  end

end

==OUTPUT==

Spec::Mocks::MockExpectationError in 'ScenesController#done
#<Scene:0x105a90708> expected :done! with (any args) once, but
received it 0 times

note: @project is assigned through a before_filter (defined in
ApplicationController) which finds the project using
params[:project_id].  it's a nested resources thang... you know

this isn't specific to the state machine plugin.  it's the same for
any instance i return from another operation within a spec.  it's as
though the @scene returned isn't receving anything, but some other
@scene (somewhere else) is receving the done! method just fine.

the sad part is, even though the spec fails, the code works in
production.  decouplization does come with headaches.  any help with
my practices wrong would definitely be appreciated and probably clear
up the same issue a dozen other times in the code.  thank you all.

VERSIONS
osx 10.6.2
rspec 1.3
rspec-rails 1.3.2
rails 2.3.5
factory-girl 1.2.2
aasm plugin
Posted by David Chelimsky (Guest)
on 2010-02-26 05:14
(Received via mailing list)
On Thu, Feb 25, 2010 at 4:44 PM, lawwantsin
<somethingnoonehasthoughtof@gmail.com> wrote:
> i'm calling a very simple should_receive method on a returned instance
> and it's saying the implementation code is not calling it.  i get this
> error in my specs alot.  i've read the rspec beta book and it doesn't
> mention examples like this.  i couldn't find any solutions on the
> forum yet so i wanted to reach out.  it seems like i'm just not
> getting something about the rspec api.
>
> ==SPEC==
>
>   before :all do

Use before(:each), especially when you're dealing with real data that
gets cleaned out after each example.

>     @scene =  Factory.create(:scene)
>     @project = Project.create(:working_title => "test")

I'd use factories for both @scene and @project:

@scene = Factory(:scene)
@project = Factory(:project, :working_title => "test")

>
> ==IMPLEMENTATION==
> class ScenesController < ApplicationController
>
>  before_filter :get_project
>
>  def done
>    @scene = @project.scenes.find(params[:id])

This @project is not the same @project that is defined in the spec,
which is likely the root of the problem. For them to be the same
object, you'll need to stub whatever method is used in the before
filter. Possibly this in the before block in the spec:

before(:each) do
  @project = Factory(:project, :working_title => "test")
  Project.stub(:find) { @project }
end

HTH,
David
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.