Search code examples
rubychef-infrachef-solocookbookchefspec

ChefSpec and Ark resources testing


I'm starting to test with chefspec, which i think is a really easy and reliable test framework. But i'm having some issues regarding to ark resources testing. I have this default_spec.rb

require 'chefspec'
require_relative 'spec_helper'

describe 'df-maven::default' do
  let (:chef_run) { ChefSpec::Runner.new.converge(described_recipe) }
  it 'should run ark' do
    expect(chef_run).to put_ark #'described_'
  end
end

Which is the test i want for my recipe df-maven::default:

include_recipe 'java::default'
include_recipe 'ark::default'

mvn_version = node['df-maven']['version'].to_s

ark 'maven' do
  url      node['df-maven'][mvn_version]['url']
  checksum node['df-maven'][mvn_version]['checksum']
  path     node['df-maven']['m2_home']
  version  node['df-maven'][mvn_version]['version']
  has_binaries ['bin/mvn']
  append_env_path true
  action :put
end

But when i run the test i get an error undefined local variable or method 'put_ark'.

Then i added this to my spec_helper (as i think matchers should do the trick):

require 'chefspec'

module ChefSpec
  module Matchers
    RSpec::Matchers.define :put_ark do |package_name|
      match do |chef_run|
        chef_run.resources.any? do |resource|
          resource_type(resource) == 'ark' and resource.name == package_name
        end
      end
    end
  end
end

But i get a undefined method resources' for #<ChefSpec::Runner:0x40a2650> error

In the real practice, it does what it is required to do, but i was asked to start making tests for all my cookbooks, so i decided to start with my df-maven cookbook.

Anyway, I think i have to define matchers, but i don't understand how to do it and make my tests to pass.


Solution

  • As documented in the ChefSpec README, in libraries/matchers.rb (for autoloading):

    if defined?(ChefSpec)
      def put_ark(resource_name)
        ChefSpec::Matchers::ResourceMatcher.new(:ark, :put, resource_name)
      end
    end
    

    If you don't want to distribute this matcher, you can put it in spec/support/something.rb:

    def put_ark(resource_name)
      ChefSpec::Matchers::ResourceMatcher.new(:ark, :put, resource_name)
    end
    

    And then require 'spec/support/something' in your spec_helper.rb.

    This will make a put_ark resource matcher/