4

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?

sethvargo
  • 26,739
  • 10
  • 86
  • 156
Abraham P
  • 15,029
  • 13
  • 58
  • 126
  • Did you ever find a solution to your problem? The syntax for ChefSpec matchers has changed since this question was posted. Does the given answer solve your problem? – sethvargo Jan 18 '14 at 21:28
  • o I'm sorry I completely forgot about this question. Gonna go recheck whats up and see – Abraham P Jan 19 '14 at 04:31

2 Answers2

7

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.

sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • The quality of my chefspec just increased by a factor of 3. Is it possible to use multiple with_content set? `should render_file('somefile').with_content(/content1/).with_content(/content2/)` only matches the 2nd regex, never parses the first. – Brett Oct 09 '14 at 12:32
  • No, with_content is not an additive matcher. – sethvargo Oct 09 '14 at 15:19
  • so the approach for testing multiple matches of content would be to assign the `.to render_file('myfile')` to a variable and then run with_content against that. – Brett Oct 10 '14 at 07:57
5

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.

Aiyesha
  • 51
  • 2