【问题标题】:stub node.attribute? in chefspec存根节点属性?在厨师长
【发布时间】:2015-08-11 12:06:09
【问题描述】:

我正在尝试为以下配方代码创建规范测试:

    if node.attribute?(node['tested_cookbook']['some_attribute'])
       include_recipe('tested_cookbook::first')
    else
       include_recipe('tested_cookbook::second')

我对此有以下规范:

    require 'spec_helper'

    describe 'tested_cookbook::default' do

    let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'windows', version: '2008R2') do |node|
    node.set['tested_cookbook']['some_attribute'] = "some_value"
    end.converge(described_recipe) }

      it 'includes recipe iis' do
         expect(chef_run).to include_recipe('tested_cookbook::first')
      end
    end

问题是这个测试总是会失败。 如何正确模拟“node.attribute”的结果? ? 谢谢你。

【问题讨论】:

    标签: unit-testing chef-infra cookbook chefspec


    【解决方案1】:

    我不确定你是否可以在没有猴子修补的情况下覆盖 Chefspec 中的节点对象,我认为这可能比它的价值更麻烦。我真的几乎从未见过node.attribute? 被使用过,所以它可能有点反模式。 (你真的关心如果它被设置了,而不是它是否有一个非零值吗?)

    我首先会避免使用attribute?,例如

    食谱:

    if node['tested_cookbook'] && node['tested_cookbook']['some_attribute'])
       include_recipe('tested_cookbook::first')
    else
       include_recipe('tested_cookbook::second')
    end
    

    规格:

    require 'spec_helper'
    
    describe 'tested_cookbook::default' do
    
    let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'windows', version: '2008R2') do |node|
    node.set['tested_cookbook']['some_attribute'] = "some_value"
    end.converge(described_recipe) }
    
      it 'includes recipe iis' do
         expect(chef_run).to include_recipe('tested_cookbook::first')
      end
    end
    

    通常的做法也给这些属性一个默认值,所以这样说会更惯用:

    属性/default.rb:

    default['tested_cookbook']['some_attribute'] = 'second'
    

    食谱:

    include_recipe "tested_cookbook::#{node['tested_cookbook']['some_attribute']}"
    

    然后在您的规范中,进行与之前相同的检查。您正在使用属性运行 ::second,但允许有人将其覆盖为 ::first。如果您不喜欢实际使用要包含的属性值的模式,您可以将其设为标志并保留之前的 if 语句。

    【讨论】:

    • 谢谢马丁,我们已经搬走了,在我们的食谱中使用了不同的方法,所以它不再是一个问题。