On 7/18/07, Mikel Lindsaar <[EMAIL PROTECTED]> 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@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users