2

I am new to unit testing and chefspec. I am trying to mock/intercept a function call in a recipe from a dependent library

  • Library

    module Helper
      def do_something_useful
        return "http://example.com/file.txt"
      end
    end
    
  • Recipe

    remote_file '/save/file/here' do
      extend Helper
      source do_something_useful
    end
    

I have tried the following:

  • Chefspec

    allow_any_instance_of(Chef::Resource::RemoteFile).to receive(:do_something_useful).and_return('foobar')
    allow_any_instance_of(Chef::Resource).to receive(:do_something_useful).and_return('foobar')
    

    I have also tried mocking with a double:

    helper = double
    Helper.stub(:new).and_return(helper)
    allow(helper).to receive(:do_something_useful).and_return('foobar')
    

    This fails with uninitialized constant Helper

mcede
  • 117
  • 5

1 Answers1

1

Sooooo this is a fun case where the extend is overwriting the mock method. So we can just use the extend to drive things:

before do
  allow_any_instance_of(Chef::Resource::RemoteFile).to receive(:extend) do |this, m|
    Module.instance_method(:extend).bind(this).call(m)
    allow(this).to receive(:do_something_useful).and_return('foobar')
  end
end

This is like 800% magic and you probably shouldn't use it, but it does work in my little test environment.

coderanger
  • 52,400
  • 4
  • 52
  • 75