title: Avoiding protected level accessors and equality methods in Ruby testing
body: <p>I have some Ruby code that uses protected level attr_readers to be able to implement an == method so that we can assert some resultant Calendar is equal to an expected Calendar), but those protected accessors would not be needed for any code besides assertions in test code.  </p>
  
  <p>Some code I have looks like this:</p>
  
  <pre><code>class Calendar    
    def initialize(date_times)
      @date_times = date_times
    end
  
    def next_date_time
      @date_times.find { |time| time - DateTime.now &gt; 0 }
    end
  
    def ==(other)
      @date_times == other.date_times
    end
  
    protected
  
    attr_reader :date_times
  end
  </code></pre>
  
  <p>How can I avoid the need for protected attr_readers?  Actually, ideally it would be great if I could remove the need for the <code>def==(......</code> as well, since it is also only needed for tests!</p>
  
  <p>All the Best,
  Alex</p>
  
  <p>A First Stab At This:</p>
  
  <pre><code>module Kernel
    def subclass_with_equals(class_symbol)
      clazz = Kernel.const_get(class_symbol.to_s)
      Kernel.subclass_with_default_equals(clazz)
    end
  
    private
  
    def self.subclass_with_default_equals(base_class)
      sub_class = Class.new(base_class)
      sub_class.class_eval do
        def ==(other)
          instance_variables.all? { |v| self.instance_variable_get(v) == other.instance_variable_get(v) } and other.instance_of? self.class
        end
      end
      sub_class
    end
  end
  </code></pre>
  
  <p>And at the top of my spec file I can add this line to add a default == method to my class:</p>
  
  <pre><code>Calendar = sub_class_with_equals :Calendar
  </code></pre>
  
  <p>This enables me to remove five or six lines from my Calendar class!</p>