"uninitialized constant" on depend cookbook

1.6k Views Asked by At

I have a guard that uses a helper library from one of my cookbook dependencies. When I create a stub for this call I receive the following error during the test run:

uninitialized constant Chef::Acme

Stub:

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

My dependencies are in my metadata file and I require the 'chefspec/berkshelf' gem in my spec_helper file.

What is the best way to handle this?

2

There are 2 best solutions below

0
On BEST ANSWER

After further testing I found a better solution. As so brilliantly stated in 1972 by Butler Lampson:

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

I created a wrapper in the libraries folder of the cookbook I'm testing which simply calls the original library and then I can stub the library call. This type of abstraction is a common pattern in testing other platforms.

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

Not sure why but the unless defined? is required for this to work.

TEST:

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

There isn't really a good option. Your cookbook library code isn't actually loaded until the runner converges, so at that point in execution your library files aren't actually loaded. One option is to use require_relative to force it to load earlier, though that can have all kinds of weird side effects. My solution was the "nuclear option" to move all my cookbooks to gems (via Halite) so I could use normal Ruby code loading rules.