Search code examples
rubyrspecrspec-rails

How to test initialize method of ruby which inturn calls the private method


# frozen_string_literal: true

require 'yaml'
require 'singleton'
require 'pry'

module Plugin
  module Rules
    class RulesLoader
      include Singleton

      attr_reader :definitions

      def initialize
        @definitions = load #it is calling the private method and loads the definitions
      end

      def fetch_rule_definition_for(key)
        definitions[key]
      end

      private
      def load
        #Other code
        Hash = {}
        #this method returns the hash after processing
      end
    end
  end
end

How to write specs for this class where the initialize method calls the private method and loads the instance variable. As the load method is private i am not calling directly.


Solution

  • I suggest rewriting it a bit with memorization.

    module Plugin
      module Rules
        class RulesLoader
          include Singleton
    
          def fetch_rule_definition_for(key)
            @definitions ||= load_definitions
            @definitions[key]
          end
    
          private
    
          def load_definitions
            #Other code
            hash = {}
            #this method returns the hash after processing
          end
        end
      end
    end
    

    A hypothetical spec:

    describe Plugin::Rules::RulesLoader do
      context '#fetch_rule_definition_for' do
        subject(:fetch_rule_definition) { described_class.instance.fetch_rule_definition_for(key) }
    
        context 'with valid key' do
          let(:key) { :valid_key }
    
          it 'returns definitions' do
            expect(fetch_rule_definition).to eq(#YOUR_VALUE_HERE#)
          end
        end
    
        context 'with invalid key' do
          let(:key) { :invalid_key }
    
          it 'returns nil' do
            expect(fetch_rule_definition).to be_nil
          end
        end
      end
    end