2016-04-15 98 views
0
$ 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' 

bar食谱运行chefspec输出Untouched Resources:所有资源的配方。 我跟着include recipe声明,但它使用allow_any_instance_of,这可能不是最佳实践。 我已经如下使用它:断言厨师运行包括从另一个食谱

$ 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 

但是当我运行rspec我得到follwing错误:

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 

可以摆脱一个问题上的光:

  1. 能chefspec运行所有包括食谱的规格?如果是这样,我可以如何配置?
  2. 如果以前是不可能的,我如何解决以上问题,并消除包括食谱(将其他食谱作为黑匣子)的衔接?

UPDATE:

也试图解决Stub (...) received unexpected message (...) with (no args)这并没有帮助,并返回一个不同的错误:

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

如果我正确理解你,你真正希望从合作社中排除'禁止'食谱资源verage报告,为此,它使用'coverage.start!'块中的'add_filter'在自述文件[此处](https://github.com/sethvargo/chefspec#reporting)的覆盖部分中进行了记录。 Chefspec不会加载包含食谱的测试,我不知道这样做的方法,包括助手/存根可能是一个想法,但它太过于猜测IMO。 – Tensibai

+0

@Tensibai:首先**感谢您的回复。请注意,添加一个过滤器并不意味着食谱将不在运行列表中,它将不在覆盖报告中,这意味着为包含的食谱创建了存根\ mocks(在我们的情况下为“bar”),将不得不复制到食谱中,包括其他食谱(在我们的例子中为'foo'),并且我们编码重复是不好的。更多的是,如果我的私人菜谱中有一个'spec_helper',全局或中心位置设置的过滤器,则需要根据每本菜谱进行修改。你有其他想法吗? – MrRoth

+0

ChefSpec是“食谱中心”,你不应该有许多食谱的共同spec_helper。假设你知道你在做什么,你可以依次要求其他食谱规格。防止包装食谱资源运行通常是错误的模式,因为您也可能错过覆盖资源。所以tl; dr;你必须有代码重复,这不是很糟糕,因为它会告诉你,如果包装食谱的更新打破你的; – Tensibai

回答

0

从Tensibai评论次数:

If I understand you properly, what you wish really is to exclude 'bar' cookbook resources from coverage report, and for this it's documented in the coverage part of the Readme here using add_filter in the coverage.start! block. Chefspec does not load the tests for included cookbook, I don't know of a way to do this, including the helpers/stubs could be an idea, but it's too much guessing IMO.