0

Cookbook: https://github.com/tkidd77/devops-project/tree/master/chef-repo/cookbooks/hello_world

My unit test:

it 'touches the correct file' do
  expect { chef_run }.to touch_file ('C:\inetpub\wwwroot\iisstart.htm')
end

Output when running "chef exec rspec" in git bash:

tkidd@tkiddhome MINGW64 /c/git/project/chef-repo/cookbooks/hello_world (master) $ chef exec rspec .F

Failures:

  1) hello_world::default touches the correct file
     Failure/Error: expect { chef_run }.to touch_file ('C:\inetpub\wwwroot\iisstart.htm')
       You must pass an argument rather than a block to use the provided matcher ( file "C:\inetpub\wwwroot\iisstart.htm"), or the matcher must implement `supports_block_expectations?`.
     # ./spec/unit/recipes/default_spec.rb:38:in `block (2 levels) in <top (required)>'

Finished in 0.07199 seconds (files took 8.68 seconds to load) 2 examples, 1 failure

Failed examples:

rspec ./spec/unit/recipes/default_spec.rb:37 # hello_world::default touches the correct file

Here is the chefspec documentation on using the touch_file test: https://www.rubydoc.info/github/acrmp/chefspec/ChefSpec/API/FileMatchers which specifies using parenthesis instead of brackets around "chef-run", but when I do that, I receive an "undefined method" error:

tkidd@tkiddhome MINGW64 /c/git/project/chef-repo/cookbooks/hello_world (master) $ chef exec rspec .F

Failures:

  1) hello_world::default touches the correct file
     Failure/Error: expect (chef_run).to touch_file ('C:\inetpub\wwwroot\iisstart.htm')

     NoMethodError:
       undefined method `to' for #<ChefSpec::SoloRunner:0x0000000007a241d8>
     # ./spec/unit/recipes/default_spec.rb:38:in `block (2 levels) in <top (required)>'

Finished in 0.04001 seconds (files took 4.92 seconds to load) 2 examples, 1 failure

Failed examples:

rspec ./spec/unit/recipes/default_spec.rb:37 # hello_world::default touches the correct file

According to this, rspec 3.0 expects a method instead of a block for the file path, but I don't understand what that would look like. How to check whether a variable is an instance of a module's subclass using rspec?

Tim Kidd
  • 3
  • 1

2 Answers2

0

That should be expect(chef_run).to touch_file('C:\inetpub\wwwroot\iisstart.htm'). You only use expect { ... } with raise_error and things like it, most matches use expect(...) as a normal call. Also you had an extra space after touch_file. method (args) is not allowed in Ruby (or at least it is allowed and doesn't do what you think it does).

coderanger
  • 52,400
  • 4
  • 52
  • 75
  • That syntax results in: Failures: 1) hello_world::default touches the correct file Failure/Error: expect(chef_run).to touch_file('C:\inetpub\wwwroot\iisstart.htm') NoMethodError: undefined method `resource_collection' for nil:NilClass # ./spec/unit/recipes/default_spec.rb:38:in `block (2 levels) in ' – Tim Kidd Sep 18 '18 at 12:41
  • Then the rest of your spec code is not correct setting up the `chef_run` object. – coderanger Sep 18 '18 at 16:45
  • That is logical, but doesn’t seem to be the case here since the other unit test works using the same chef_run object: describe 'hello_world::default' do let :chef_run do ChefSpec::SoloRunner.new(platform: 'windows', version: '2016') end it 'converges successfully' do expect { chef_run }.to_not raise_error end – Tim Kidd Sep 19 '18 at 14:32
  • You’re missing a .converge(something) in there – coderanger Sep 19 '18 at 16:54
0

Solution:

describe 'hello_world::default' do

  let :chef_run do
    ChefSpec::SoloRunner.new(platform: 'windows', version: '2016').converge(described_recipe)
  end

     it 'touches the correct file' do
       expect(chef_run).to touch_file('C:\inetpub\wwwroot\iisstart.htm')
     end
end
Tim Kidd
  • 3
  • 1