0
# 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.

Honnappa
  • 17
  • 1
  • 6
  • If you need to wrap `load` into another method, why would you use the constructor for that? You can simply create the method `definitions`, or use an alias. – Sebastián Palma May 12 '20 at 09:42

1 Answers1

0

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
Yakov
  • 3,033
  • 1
  • 11
  • 22
  • @Mahant Cool. Could you please mark my answer as a correct one if it is? – Yakov May 15 '20 at 07:00
  • Hi, I want one more improvement required on the above code. def initialize @definitions = load(path) end Now the initialize method is calling load methos with the path. The load method will check each yml files in that path and adds the content of yml file to hash. Now i wanted to test the load method which is private. So i have created a fixtures folder and adding all the yml files in them. subject(:fetch_rule_definition) { described_class.instance.fetch_rule_definition_for(key) } How do i call described_class.instance with a parameter. The parameter is fixture path – Honnappa May 19 '20 at 07:34
  • Hi. Take a look here https://stackoverflow.com/questions/5259398/ruby-create-singleton-with-parameters – Yakov May 19 '20 at 07:48