rubychefspec

ChefSpec Ruby: How to skip all includes (allow_any_instance_of) but one?


I would like to test whether a certain include which is subject to conditions is being executed. All other includes should not be taken into account in the test and therefore should not be included.

My file that I want to test looks like this:

include_recipe 'test::first_recipe'

if set_is_two?
   include_recipe 'test::second_recipe'
end

In my test I want to test that the file "test::second_recipe" is included if the function "set_is_two" returns true. At the same time I don't want to have to include all other files like "test::first_recipe" in the test.

Unfortunately, my current approach does not work. All other includes are prevented, but the "test::second_recipe" is apparently not included as well.

before do
    # skip all includes
    allow_any_instance_of(Chef::Recipe).to receive(:include_recipe)
    allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('test::second_recipe')

    allow_any_instance_of(Chef::Recipe).to receive(:set_is_two?).and_return(true)
end

it { is_expected.to include_recipe('include_recipe::test::second_recipe') }

It seems as if my first "allow_any_instance_of" skips everything, but nothing is enabled afterwards.


Solution

  • I found the answer to my problem at this post

    before(:all) { @included_recipes = [] }
    before do
      @stubbed_recipes = %w[test_cookbook::included_recipe apt]
      @stubbed_recipes.each do |r|
        allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with(r) do
          @included_recipes << r
        end
      end
    end
    
    it 'includes the correct recipes' do
      chef_run
      expect(@included_recipes).to match_array(@stubbed_recipes)
    end
    

    Using this example code, it is working as expected.