2016-04-15 97 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.