Re: [rspec-users] Rails - Mock going out of scope?
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
Re: [rspec-users] Rails - Mock going out of scope?
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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] wrote: Would you mind posting the migrations? On 7/18/07, Mikel Lindsaar [EMAIL PROTECTED] 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 [EMAIL PROTECTED] wrote: 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
Re: [rspec-users] Rails - Mock going out of scope?
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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] wrote: Would you mind posting the migrations? On 7/18/07, Mikel Lindsaar [EMAIL PROTECTED] 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 [EMAIL PROTECTED] wrote: 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