Assert that the Chef run included a recipe from another cookbook

时间:2016-04-15 14:50:16

标签: chef cookbook

$ cat Gemfile | grep "'chefspec'\|'chef'"
  gem 'chef', '12.8.1'
  gem 'chefspec', '4.6.1'

$ cat cookbooks/foo/recipes/default.rb | grep include
include_recipe 'bar'

$ cat cookbooks/foo/metafata.rb | grep depends
depends 'bar'

running chefspec output Untouched Resources: for all resources in bar cookbook. i followed include recipe assertion, but it uses allow_any_instance_of, which might not be a best practice. i've used it as follows:

$ cat cookbook/foo/spec/recipes/default_spec.rb
describe 'foo::default' do
  cached(:chef_run) { ChefSpec::ServerRunner.converge(described_recipe) }
  let(:recipe) { instance_double(Chef::Recipe, cookbook_name: 'foo', recipe_name: 'default') }

  before do
    allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).and_call_original
    allow_any_instance_of(recipe).to receive(:include_recipe).with('bar')
  end

  it 'includes recipes' do
    expect_any_instance_of(recipe).to receive(:include_recipe).with('bar')
  end
end

but when i run rspec i get the follwing error:

foo::default
  includes recipes (FAILED - 1)

Failures:

  1) foo::default includes recipes
     Failure/Error: allow_any_instance_of(recipe).to receive(:include_recipe).with('bar')
       #<InstanceDouble(Chef::Recipe) (anonymous)> received unexpected message :ancestors with (no args)
     # ./vendor/cookbooks/foo/spec/recipes/default_spec.rb:32:in `block (2 levels) in <top (required)>'

Finished in 2.22 seconds (files took 1.72 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./vendor/cookbooks/foo/spec/recipes/default_spec.rb:43 # foo::default includes recipes

can one shed the light on the issue:

  1. can chefspec ran the spec of all included cookbooks? if so, how i can be configured?
  2. if the previous is not possible, how can i fix the above and eliminate the converge of included cookbooks (treat other cookbooks as a blackbox)?

UPDATE:

tried also the solution Stub (...) received unexpected message (...) with (no args) which did not help, and returned a different error:

foo::default
  includes recipes (FAILED - 1)

Failures:

  1) foo::default includes recipes
     Failure/Error: allow(recipe).to receive(:ancestors).and_return(true)
       the Chef::Recipe class does not implement the instance method: ancestors. Perhaps you meant to use `class_double` instead?
     # ./vendor/cookbooks/foo/spec/recipes/default_spec.rb:31:in `block (2 levels) in <top (required)>'
     # ./vendor/cookbooks/foo/spec/recipes/default_spec.rb:37:in `block (2 levels) in <top (required)>'

Finished in 1.33 seconds (files took 1.4 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./vendor/cookbooks/foo/spec/recipes/default_spec.rb:48 # foo::default includes recipes

1 个答案:

答案 0 :(得分:0)

摘自Tensibai评论:

  

如果我理解你,你真正想要的是从报道报告中排除'bar'食谱资源,为此,它在自述文件的覆盖部分中使用cover.start中的add_filter进行了记录!块。 Chefspec没有为包含的食谱加载测试,我不知道如何做到这一点,包括帮助者/存根可能是一个想法,但它太多猜测IMO。