I have a cookbook that installs a list of packages provided by node attributes. Is it possible to test this type of package installation with chefspec? As it is now, I receive an error:
1) foo::default installs test-package-1
Failure/Error: expect(chef_run).to install_package(pkg)
expected "package[test-package-1]" with action :install to be in Chef run. Other package resources:
package[["test-package-1", "1.0.0"]]
package[["test-package-2", "1.2.3"]]
Chefspec isn't seeing that the package is being installed, even though it's listed right there! Surely I'm missing something obvious here.
Here's the relevant cookbook files:
node.default['foo']['packages'] = {
'test-package-1' => '1.0.0',
'test-package-2' => '1.2.3'
}
node['foo']['packages'].each do |pkg|
package pkg do
version node['foo']['packages'][pkg]
action :install
end
end
describe "foo::default" do
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
%w(
test-package-1
test-package-2
).each do |pkg|
it "installs #{pkg}" do
expect(chef_run).to install_package(pkg)
end
end
end
Ruby's Hash#each
is an alias for each_pair
, not each_key
. This is different from languages like Python and JavaScript which default to iterating over the keys. In this case your test is correct in showing you that your recipe code is wrong :-)
node['foo']['packages'].each do |pkg, pkg_ver|
package pkg do
version pkg_ver
action :install
end
end