依赖食谱的“未初始化的常数”

时间:2016-02-26 17:02:39

标签: chef chefspec

我有一个使用我的某个cookbook依赖项中的帮助程序库的守卫。当我为此调用创建存根时,我在测试运行期间收到以下错误:

uninitialized constant Chef::Acme

存根:

before(:each) do
  allow(Chef::Acme::Helper).to receive(:is_widget_requested?).and_return(true)
end

我的依赖项在我的元数据文件中,我的spec_helper文件中需要'chefspec / berkshelf'宝石。

处理此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

真的不是一个好选择。您的菜谱库代码在转轮收敛之前并未实际加载,因此在执行时您的库文件实际上并未加载。一种选择是使用require_relative强制它加载更早,尽管这可能有各种奇怪的副作用。我的解决方案是"核选项"把我所有的食谱都移到宝石上(通过Halite)所以我可以使用普通的Ruby代码加载规则。

答案 1 :(得分:0)

经过进一步测试,我找到了更好的解决方案。正如巴特勒兰普森在1972年所阐述的那样出色:

  

“计算机科学中的所有问题都可以通过另一个层面来解决   间接“

我在我正在测试的cookbook的libraries文件夹中创建了一个包装器,它只调用原始库然后我可以存根库调用。这种类型的抽象是测试其他平台的常见模式。

WRAPPER:

class Chef
    class Acme
        class HelperWrapper
            public
                def self.is_widget_requested?(node)
                    Chef::Acme::Helper.is_widget_requested?(node)
                end
        end unless defined?(HelperWrapper)
    end
 end

不确定原因,但unless defined?是必需的。

TEST:

before(:each) do
    allow(Chef::Acme::HelperWrapper).to receive(:is_widget_requested?).and_return(true)
end