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

Mikel Lindsaar raasdnil at gmail.com
Thu Jul 19 01:28:03 EDT 2007


Makes total sense.

Thank you _very_ much David :)  All works well and handles another
question I have on a disrelated matter.

By the way, loving RSpec.  Makes testing a lot more interesting and
rewarding.  Thanks for all your work.

Regards

Mikel

On 7/19/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> D'oh. I should have figured this out on first sighting:
>
> The parent method does a find, so it retrieves a new object from the
> db - not the instance of Node you have defined. This new instance has
> no language associated with it (because the one you gave it pretends
> to exist by sporting an ID, but is never saved to the DB).
>
> Make sense?
>
> So, if you want to mock this, you have to mock a bit more than what
> you have in mind. Check out this pastie:
> http://pastie.textmate.org/80159
>
> David
>
> On 7/19/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:
> > Using 1.2.3 and RSpec with the RSpec Rails plugin installed from
> > CURRENT on the RSpec SVN server.
> >
> > On 7/19/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:
> > > Crap, I totally, forgot to mention, sorry David.  I am using betternestedset
> > >
> > > http://wiki.rubyonrails.org/rails/pages/BetterNestedSet
> > >
> > > script/plugin source svn://rubyforge.org/var/svn/betternestedset
> > > script/plugin install betternestedset
> > >
> > >
> > > Regards
> > >
> > > Mikel
> > >
> > > On 7/19/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > > Here are the errors I'm getting now:
> > > >
> > > > 1)
> > > > NoMethodError in 'Node instance should return it's parent's language
> > > > if it is a child'
> > > > undefined method `move_to_child_of' for #<Node:0x34d3110>
> > > > ./spec/models/node_spec.rb:20:
> > > >
> > > > 2)
> > > > NameError in 'Node instance should return it's own language if it is root'
> > > > undefined local variable or method `parent' for #<Node:0x34b8ef0>
> > > > /Users/david/projects/ruby/nodes/config/../app/models/node.rb:7:in
> > > > `language_name'
> > > > ./spec/models/node_spec.rb:16:
> > > >
> > > > What version of rails are you using? And is there a plugin you're
> > > > using for nested set?
> > > >
> > > > David
> > > >
> > > > On 7/19/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:
> > > > > Here are the migrations:
> > > > >
> > > > > class CreateNodes < ActiveRecord::Migration
> > > > >   def self.up
> > > > >     create_table ("nodes", :options => 'ENGINE=InnoDB DEFAULT
> > > > > CHARSET=utf8', :force => true) do |t|
> > > > >       t.column "title",            :string
> > > > >       t.column "language_id",      :integer
> > > > >       t.column "parent_id",        :integer
> > > > >       t.column "lft",              :integer
> > > > >       t.column "rgt",              :integer
> > > > >       t.column "original_node_id", :integer
> > > > >       t.column "owner_id",         :integer
> > > > >       t.column "owner_type",       :string
> > > > >       t.column "root_id",          :integer
> > > > >     end
> > > > >   end
> > > > >
> > > > >   def self.down
> > > > >     drop_table "nodes"
> > > > >   end
> > > > > end
> > > > >
> > > > > class CreateLanguagesTable < ActiveRecord::Migration
> > > > >   def self.up
> > > > >     create_table (:languages, :options => 'ENGINE=InnoDB DEFAULT
> > > > > CHARSET=utf8', :force => true) do |t|
> > > > >       t.column :name, :string
> > > > >     end
> > > > >   end
> > > > >
> > > > >   def self.down
> > > > >     drop_table :languages
> > > > >   end
> > > > > end
> > > > >
> > > > >
> > > > > The Nodes Model also has a self referrential association, but I don't
> > > > > think that would be causing any problems.
> > > > >
> > > > > class Node < ActiveRecord::Base
> > > > >   belongs_to :language
> > > > >   belongs_to :owner, :polymorphic => true
> > > > >
> > > > >   # Self referrential association, nodes have many original nodes - keeps track
> > > > >   # of all original => translation associations
> > > > >   belongs_to :original_node, :class_name => "Node", :foreign_key =>
> > > > > "original_node_id"
> > > > >   has_many :translated_nodes, :class_name => "Node", :foreign_key =>
> > > > > "original_node_id"
> > > > >
> > > > >   acts_as_nested_set :scope => :root_id
> > > > >
> > > > >   #  + code from the original pastie
> > > > >
> > > > > end
> > > > >
> > > > >
> > > > > There are some other associations, but they are all belongs_to or
> > > > > has_many, so I haven't bothered to put all the tables in here and have
> > > > > removed the appropriate foreign keys from the nodes table.
> > > > >
> > > > >
> > > > > Regards
> > > > >
> > > > > Mikel
> > > > >
> > > > >
> > > > > On 7/19/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > > > > Would you mind posting the migrations?
> > > > > >
> > > > > > On 7/18/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:
> > > > > > > Heya David,
> > > > > > >
> > > > > > > Thanks for the reply.
> > > > > > >
> > > > > > > No, that didn't work, get the same 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
> > > > > > >
> > > > > > >
> > > > > > > If I include the fixture :languages, then replace out @language =
> > > > > > > mock_model... with
> > > > > > >
> > > > > > > @language = languages(:one)
> > > > > > >
> > > > > > > it all works dandy.  But I'm trying to ween myself off fixtures :)
> > > > > > >
> > > > > > > Regards
> > > > > > >
> > > > > > > Mikel
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On 7/19/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > > > > > > 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
> > > > > > > > >
> > > > > > > > _______________________________________________
> > > > > > > > rspec-users mailing list
> > > > > > > > rspec-users at rubyforge.org
> > > > > > > > http://rubyforge.org/mailman/listinfo/rspec-users
> > > > > > > >
> > > > > > > _______________________________________________
> > > > > > > rspec-users mailing list
> > > > > > > rspec-users at rubyforge.org
> > > > > > > http://rubyforge.org/mailman/listinfo/rspec-users
> > > > > > >
> > > > > > _______________________________________________
> > > > > > rspec-users mailing list
> > > > > > rspec-users at rubyforge.org
> > > > > > http://rubyforge.org/mailman/listinfo/rspec-users
> > > > > >
> > > > > _______________________________________________
> > > > > rspec-users mailing list
> > > > > rspec-users at rubyforge.org
> > > > > http://rubyforge.org/mailman/listinfo/rspec-users
> > > > >
> > > > _______________________________________________
> > > > rspec-users mailing list
> > > > rspec-users at rubyforge.org
> > > > http://rubyforge.org/mailman/listinfo/rspec-users
> > > >
> > >
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list