1

そのため、Chef レシピの 1 つに対して単体テスト (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'
4

1 に答える 1

1

何が起こっているかは次のとおりです。

node[:rvm][:install_pkgs]

返品中nilです。したがって、呼び出しnil.eachて例外を取得しています。残念ながら、その属性がnil.

依存

あなたのクックブックで、あなたのクックtheoracleブックへの依存関係を追加しましたか?rvmmetadata.rb

depends 'rvm'

この行がないと、Chef は RVM クックブックをロードせず (したがって、その属性をロードしない)、install_pkgs属性が になりますnil

デフォルトの属性 (可能性が高い)

クックブックでその属性の値を決定するためのコードを見ると、次の条件下でのみ設定されているchef-rvmことがわかります。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 に特定の OS のように動作するように指示します。

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
于 2014-08-13T17:36:20.037 に答える