Test file initialization based off template using ChefSpec

2.6k views Asked by At

I've got the following template file creation in my cookbook:

template "my_file" do
  path "my_path"
  source "my_file.erb"
  owner "root"
  group "root"
  mode "0644"
  variables(@template_variables)
  notifies :restart, resources(service: "my_service")
end

and the following assertions in my ChefSpec tests:

  chef_run.should create_file "my_file"
  chef_run.file("my_file").should be_owned_by('root', 'root')

Which results in the following failure:

  No file resource named 'my_file' with action :create found.

This is due to the fact that I am not using afile resource but a template resource. Question: How can I test for file creation off a template resource using ChefSpec?

2

There are 2 answers

3
sethvargo On BEST ANSWER

There are two ways to solve your problem.

First, you can use the create_template matcher. This will match only "template" resources in the run context:

expect(chef_run).to create_template('my_file')

This matcher is also chainable, so you can assert attributes:

expect(chef_run).to create_template('my_file')
  .with_path('my_path')
  .with_owner('root')

However, this matcher won't actually render the template. So you can't check if you've setup file-specificity correctly.

There's also a top-level matcher for any kind of "file" (file, cookbook_file, and template) that actually renders the contents in memory:

expect(chef_run).to render_file('my_file').with_content(/^match me$/)

You can find more information about render_file in the README.

0
Aiyesha On

According to the docs (https://github.com/acrmp/chefspec) you should be able to use:

expect(chef_run).to create_file 'my_file'

I think something changed very recently (possibly the version of chefspec on rubygems), however, because tests I had passing earlier today (using the same syntax you are using) are now suddenly failing.