[mocha-developer] Stubbing ActiveRecord Models gets very difficult with instance methods

John Pywtorak jpywtora at calpoly.edu
Wed Jan 3 14:02:05 EST 2007

James Mead wrote:
> Stubbing attributes sounds like a bad idea.
> Turning instance methods into class methods for testing sounds like a bad idea.
> We do choose to allow the database trip to determine model attributes.
> In my opinion, it's not worth mocking this out.
> Can you give a concrete example of an instance method you are having
> problems testing? Examples are much easier to discuss without
> ambiguity.

I couldn't agree more.  And, here is an example.

module Fear
   module Models
     class StatsTb < ActiveRecord::Base
       set_table_name "w.stats_tb"

       def check_stat
         h, m = maint_time.split(":").map(&:to_i)
         m_dt = maint_dt.to_time + m.hours + m.minutes
         now = Time.now
         m_dt.day == now.day && now - m_dt > 0

       def self.find_stats
         stats = []
         %w(P_TB P_CURRENT_FLAGS_TB X_TB).each do |tb|
           stats << StatsTb.find_by_table_name(
             tb, :order => "maint_dt desc nulls last", :readonly => true

This example is not meant to serve as a best solution, or even a good 
solution.  It is only for demonstrating difficulty of stubbing for 
ActiveRecord model instance methods testing.

So, you can see from the model we have a table with maint_time, 
maint_dt, and table_name columns.  StatsTb#check_stat is attempting to 
verify a given instance of StatsTb.  So, how would one go about writing 
a test for check_stat, specifically using mocha?  Also, attempting to 
eliminate all trips to the database, because testing #check_stat does 
not need it.  The db connection and all the active record magic are 
tested elsewhere right?

So, here was a first attempt example:
require 'test/unit'
require 'date'
require 'fear'
class ModelsTest < Test::Unit::TestCase
   attr :stat

   def setup
     @stat = stub(:table_name => "P_TB", :maint_dt => Date.today, 
:maint_time => "00:00")

   def test_check
     StatsTb.find_stats.each { |st| assert st.check }

So, this does not work, because the blocks st object is not an instance 
a real instance with a check method and I can't stub check, because it 
is the method under test.

Thanks James for any advice and suggestions.

More information about the mocha-developer mailing list