所以我试图为我的一个厨师食谱编写一个单元测试(通过ChefSpec),但我得到一些奇怪的行为。
我的问题是包含rvm :: system_install配方,显然这会导致ChefSpec出现问题:
Failures:
1) theoracle::prereqs installs libyaml libyaml-devel sqlite-devel
Failure/Error: let(:chef_run) { ChefSpec::Runner.new.converge('theoracle::prereqs')}
NoMethodError:
undefined method `each' for nil:NilClass
# /Users/jdoe/workspace/cookbooks/rvm/libraries/chef_rvm_recipe_helpers.rb:44:in `install_pkg_prereqs'
# /Users/jdoe/workspace/cookbooks/rvm/recipes/system_install.rb:29:in `from_file'
# ./recipes/prereqs.rb:22:in `from_file'
# ./spec/unit/recipes/prereqs_spec.rb:6:in `block (2 levels) in <top (required)>'
# ./spec/unit/recipes/prereqs_spec.rb:15:in `block (2 levels) in <top (required)>'
违规代码段:
/Users/jdoe/workspace/cookbooks/rvm/libraries/chef_rvm_recipe_helpers.rb:
41: def install_pkg_prereqs(install_now = node.recipe?("rvm::gem_package"))
42: return if mac_with_no_homebrew
43:
44>> node[:rvm][:install_pkgs].each do |pkg|
45: p = package pkg do
这就是我的测试结果:
require 'spec_helper'
describe 'theoracle::prereqs' do
let(:chef_run) { ChefSpec::Runner.new.converge('theoracle::prereqs')}
it 'installs libyaml libyaml-devel sqlite-devel' do
%W( libyaml libyaml-devel sqlite-devel ).each do |pkg|
expect(chef_run).to_install_package(pkg)
end
end
end
这是theoracle::prereqs
食谱(部分内容):
%W( libyaml libyaml-devel sqlite-devel ).each do |pkg|
package pkg do
action :install
end
end
include_recipe 'rvm::system_install'
答案 0 :(得分:1)
以下是发生的事情:
node[:rvm][:install_pkgs]
正在返回nil
。因此,您正在调用nil.each
并获取异常。不幸的是,为什么该属性可能是nil
。
在theoracle
食谱中,您是否已在rvm
添加了对metadata.rb
食谱的依赖?
depends 'rvm'
如果没有这一行,Chef将不会加载RVM cookbook(因此不会加载其属性),导致install_pkgs
属性为nil
。
如果您在chef-rvm
食谱中look at the code for determining the value of that attribute,则可以看到node[:rvm][:install_pkgs]
仅在以下条件下设置:
case platform
when "redhat","centos","fedora","scientific","amazon"
node.set['rvm']['install_pkgs'] = %w{sed grep tar gzip bzip2 bash curl git}
default['rvm']['user_home_root'] = '/home'
when "debian","ubuntu","suse"
node.set['rvm']['install_pkgs'] = %w{sed grep tar gzip bzip2 bash curl git-core}
default['rvm']['user_home_root'] = '/home'
when "gentoo"
node.set['rvm']['install_pkgs'] = %w{git}
default['rvm']['user_home_root'] = '/home'
when "mac_os_x", "mac_os_x_server"
node.set['rvm']['install_pkgs'] = %w{git}
default['rvm']['user_home_root'] = '/Users'
end
对于ChefSpec,所有Ohai数据(设置platform
键的内容)都被模拟为允许控制此行为。 最有可能,ChefSpec将其平台报告为chefspec
,由于case
语句没有默认块,因此该属性为nil
。
要解决此问题,请告诉ChefSpec表现得像某个特定操作系统:
ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04')
或者在测试中手动设置属性:
let(:chef_run) do
ChefSpec::Runner.new do |node|
node.set['rvm']['install_pkgs'] = %w(whatever)
end.converge(described_recipe)
end