"uninitialized constant" 取决于食谱

"uninitialized constant" on depend cookbook

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

uninitialized constant Chef::Acme

存根:

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

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

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

没有很好的选择。在运行器收敛之前,您的食谱库代码实际上并未加载,因此在执行时您的库文件并未实际加载。一种选择是使用 require_relative 强制它提前加载,尽管这可能会产生各种奇怪的副作用。我的解决方案是 "nuclear option" 将我所有的食谱移动到 gems(通过 Halite),这样我就可以使用正常的 Ruby 代码加载规则。

经过进一步测试,我找到了更好的解决方案。正如巴特勒·兰普森 (Butler Lampson) 在 1972 年的精彩表述:

"All problems in computer science can be solved by another level of indirection"

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

包装器:

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? 才能正常工作。

测试:

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