chef の ruby_block 内でリソースを実行するで書いたようなレシピをテストしたい。こんなの。
recipes/foo.rb
recipe = self
ruby_block "foo" do
block do
contents = File.read("/tmp/foo")
recipe.log "foo" do
message contents
end
end
end
chefspec は次のように書けば良い
spec/recipes/foo_spec.rb
require 'chefspec'
describe 'cookbook-name::foo' do
let(:chef_run) do
ChefSpec::SoloRunner.new do |node|
end.converge(described_recipe)
end
before do
# File.read に stub をあてるにはこう
allow(File).to receive(:read).and_call_original
allow(File).to receive(:read).with("/tmp/foo") { "foo" }
# ruby_block の中を実行するにはこう。
# old_run_action は chefspec が挿げ替える前の chef の本物の run_action
chef_run.ruby_block('foo').old_run_action(:run)
end
it do
# いつものような expect(chef_run).to action_resource は利かない
expect(chef_run.log("foo").message).to eql("foo")
end
it "いつものように expect(chef_run).to action_resource したい場合" do
# chefspec が呼んでくれなくなっているので 自分で run_action を呼ぶ
# action 名を指定しているので、action のテストにはならないかも
chef_run.log('foo').run_action(:write)
expect(chef_run).to write_log("foo").with(message: "foo")
end
end
execute#run_action(:run)
してしまえば、stub_command もあてられる