如何通过rspec存根静态类方法

时间:2013-08-06 07:03:13

标签: ruby-on-rails unit-testing rspec rspec-rails

我有一个静态方法,通过进行外部服务调用来启动静态变量。我想存根静态方法调用,以便在初始化类变量时不进行外部服务调用。 这是一个简单的代码示例。

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

现在我想用我的对象存根静态方法调用,以便使用我想要的响应初始化@@ config。 我已经尝试了几件事,我似乎没有用我的对象初始化@@ config,而只是通过实现的调用。

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

我甚至尝试使用spec_helper中的存根,尽管它会在执行到达那里时初始化类变量之前执行,但这也没有帮助。我现在坚持了一段时间。有人请成为救世主。

2 个答案:

答案 0 :(得分:1)

而不是存根“:ini”方法,我认为你不能这样做,因为解析器在调用stub方法之前经过了ABC定义,我建议你将类变量@@ config设置为你想要的前一块价值:

before(:each) do
  ABC.class_variable_set(:@@config, myObject)
end

然后试着看看这是否能解决你的问题。

答案 1 :(得分:1)

您的问题是,在加载类@@config时正在进行ABC的初始化,并且您无法通过存根干预该过程。如果你不能自己存根外部调用,那么我唯一能想到的就是改变类定义以包含一个单独的类初始化方法。