[rspec-users] Rails - Mock going out of scope?

David Chelimsky dchelimsky at gmail.com
Wed Jul 18 23:24:59 EDT 2007


On 7/18/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:
> Hello list,
>
> I think I have a rails related RSpec problem with a mock going out of
> scope on a recursive call to a model.
>
> The code is at: http://pastie.textmate.org/79821 if you want to see it
> highlighted.  I have pasted it below as well.
>
> Basically, I have an acts_as_nested_set model called "Node", which
> works fine.  I have a function which finds the language name of the
> node instance.  If the language is nil for the node instance being
> queried, it then recursively calles language_name on it's parent until
> one of them has the language.  Then this gets returned.
>
> When I do this with a fixture, it works fine.  Ie, a Database call can
> be made to a language table and I get the language name.
>
> In the code attached it has a langauge instance being mocked.  I get
> the same result if I mock Language.should_receive(:find)...
>
> It SEEMS like the Mock is going out of scope on the recursive call to
> parent.  The direct spec to the parent to get language name works
> fine.
>
> Any ideas? (the code below is slimmed down to the code needed to run the spec.
>
> Regards
>
> Mikel
>
> CODE::
>
> class Node < ActiveRecord::Base
>
>   belongs_to :language
>   acts_as_nested_set :scope => :root_id
>
>   def language_name
>     self.root? ? language.name : parent.language_name
>   end
> end
>
> describe Node, "instance" do
>
>   fixtures :nodes
>
>   before(:each) do
>     @language = mock_model(Language, :name => "Japanese")
>     @node = Node.create!(:language => @language)
>     @section1 = Node.create!()
>     @chapter1 = Node.create!()
>   end
>
>   it "should return it's own language if it is root" do  # Passes
>     @language.should_receive(:name).exactly(:once).and_return("Japanese")
>     @node.language_name.should == "Japanese"
>   end
>
>   it "should return it's parent's language if it is a child" do #
> Fails (message below)
>     @section1.move_to_child_of(@node)
>     @chapter1.move_to_child_of(@section1)
>     @language.should_receive(:name).exactly(:once).and_return("Japanese")
>     @section1.language_name.should == "Japanese"
>     @language.should_receive(:name).exactly(:once).and_return("Japanese")
>     @chapter1.language_name.should == "Japanese"
>   end
> end

It's generally not recommended that you set expectations, invoke them
and then set them again. I'm not sure, but that may be the problem
here. Try this:

  it "should return it's parent's language if it is a child" do #
Fails (message below)
    @section1.move_to_child_of(@node)
    @chapter1.move_to_child_of(@section1)
    @language.should_receive(:name).exactly(:twice).and_return("Japanese")
    @section1.language_name.should == "Japanese"
    @chapter1.language_name.should == "Japanese"
  end

Does that work?

>
> SPEC ERROR::
>
> NoMethodError in 'Node instance should return it's parent's language
> if it is a child'
> You have a nil object when you didn't expect it!
> The error occurred while evaluating nil.name
> /Users/mikel/working/universal_translator/config/../app/models/node.rb:29:in
> 'language_name'
> /Users/mikel/working/universal_translator/config/../app/models/node.rb:29:in
> 'language_name'
> ./spec/models/node_spec.rb:160:
> script/spec:4:
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list