Ruby / ChefSpec coding style feedback

I am new to Ruby, but over the past two weeks I have done a lot of research on testing a chef. This test uses ChefSpec and Fauxhai, but it doesn't look very ruby, and I was hoping the community could give me some pointers to the coding style. Is there a better way to write a nested loop like this?

cookbooks / Foo / Recipes / default.rb

package "foo" do action :install end 

cookbooks / Foo / specs / default_spec.rb

 require 'chefspec' describe 'foo::default' do platforms = { "debian" => ['6.0.5'], "ubuntu" => ['12.04', '10.04'], "centos" => ['5.8', '6.0', '6.3'], "redhat" => ['5.8', '6.3'], "mac_os_x" => ['10.6.8', '10.7.4', '10.8.2'], "windows" => ['2008R2'] } platforms.each do |platform,versions| versions.each do |version| context "on #{platform} #{version}" do before do Fauxhai.mock(platform: platform, version: version) end it 'should install foo' do @runner = ChefSpec::ChefRunner.new.converge('foo::default') @runner.should install_package 'foo' end end end end end 

Any and all feedback is welcome. Thanks!

+6
source share
1 answer

First, it is common practice to retrieve a ChefRunner instance of let helper. You can also enable the entire Fauxhai configuration:

 let(:chef_run) do ChefSpec::ChefRunner.new(platform: platform, version: version) do |node| node.set['foo']['bar'] = 'baz' # .... end.converge('foo::default') end it "installs foo" do expect(chef_run).to install_package 'foo' end 

The expect syntax seems to be recommended over should . But in this example, I would use a single line:

 subject do ChefSpec::ChefRunner.new(platform: platform, version: version).converge('foo::default') end it { should install_package 'foo' } 

To clear the loop a bit, you can use common RSpec examples . A slightly more advanced example:

 require 'chefspec' shared_examples 'foo' do |platform, version| context "on #{platform} #{version}" do let(:users) { %w[user1 user2] } let(:chef_run) do ChefSpec::ChefRunner.new(platform: platform, version: version) do |node| node.set['foo']['users'] = users end.converge('foo::default') end subject { chef_run } it { should install_package 'foo' } it "creates specified users" do users.each { |u| expect(chef_run).to create_user u } end end end describe 'foo::default' do platforms = { 'debian' => ['6.0.5'], 'ubuntu' => ['12.04', '10.04'], 'centos' => ['5.8', '6.0', '6.3'], 'redhat' => ['5.8', '6.3'], 'mac_os_x' => ['10.6.8', '10.7.4', '10.8.2'], 'windows' => ['2008R2'] } platforms.each do |platform, versions| versions.each do |version| include_examples 'foo', platform, version end end end 
+6
source

All Articles