From theniels at gmail.com Fri May 2 09:35:28 2008 From: theniels at gmail.com (Niels Bergsland) Date: Fri, 2 May 2008 09:35:28 -0400 Subject: [Flexmock-users] Partial mock on a rails class Message-ID: Hi flexmock users, A coworker of mine and I have been using flexmock (and have been very happy with it!) and ran into a strange issue last night when partial mocking one of our rails classes. We have AnalysisFile objects which belong to an Analysis. All of our Analysis objects currently belong to one of two different types of objects. Both of those objects implement a method called subject which returns a Subject object. As a convenience method, we added the subject method to AnalysisFile. The code is as follows: class AnalysisFile belongs_to :analysis #snipped def subject owner = self.analysis.owner unless owner.respond_to?(:subject) raise RuntimeError.new( 'Owner does not know about any owning subject.') end return owner.subject end #snipped end We wanted to use flexmock to test the part of the code that raises the RuntimeError. Our original idea was to do the following: def test_find_subject analysis_file = analyses_files(:fll_roi) analysis = analysis_file.analysis mock_analysis = flexmock(analysis) mock_analysis.should_receive(:owner).and_return(1) analysis_file.analysis = mock_analysis assert_raise(RuntimeError) do analysis_file.subject end end Unfortunately, this did not work as it resulted in: NoMethodError: You have a nil object when you didn't expect it! The error occurred while evaluating nil.should_receive /usr/local/lib/ruby/gems/1.8/gems/flexmock-0.8.0/lib/flexmock/partial_mock.rb:95:in `should_receive' analysis_file_test.rb:50:in `test_find_subject' Interestingly though (at least to us!) was that if we changed mock_analysis = flexmock(analysis) to mock_analysis = flexmock(analysis.reload) The test worked fine! We thought it was something with the way Rails lazy loads objects from the database. But calling other methods on analysis before flexmock(analysis), to effectively force loading from the database, still resulted in the NoMethodError. Are we doing something fundamentally wrong and that calling reload is causing the test to work by coincidence? Thanks for any insight! -Niels