Search code examples
ruby-on-railsunit-testingrspecrspec-rails

How to stub static class methods through rspec


I have a static method which initiates a static variable by making a external service call. I want to stub that static method call so that external service call is not made while initializing of the class variable. here is an example of my code in simple terms.

class ABC
    def self.ini
        return someCallToMyExternalLibrary # i don't want the execution to go there while testing
    end

    @@config = self.ini

    def method1
        return @@config['download_URL']
    end
end

Now I want to stub the static method call with my object so that @@config is initialized with the response which I want to get. I have tried several things and I seems that @@config is not initialized with my object but by the implemented call only.

describe ABC do
    let(:myObject) { Util.jsonFromFile("/data/app_config.json")}
    let(:ABC_instance) { ABC.new }

    before(:each) do
        ABC.stub(:ini).and_return(myObject)
    end

    it "check the download url" do
        ABC_instance.method1.should eql("download_url_test")
        # this test fails as @@config is not getting initialized with my object
        # it returns the download url as per the implementation.
    end

end

I have even tried stubing in the spec_helper with the though that it will be executed first before the class variable is initialized when execution reaches there, but that also did not help. I am stuck with this now for a while. Someone please be a Savior.


Solution

  • Your problem is that the initialization of @@config is occurring while the class ABC is being loaded and there is no way for you intervene in that process via stubbing. If you cannot stub the external call itself, then the only thing I can think of is to change the class definition to include a separate class initialization method.