Example of mocking out a library in Chef so you can test the provider in isolation.
If you want to test the library itself you can do more normal Ruby things.
Example of mocking out a library in Chef so you can test the provider in isolation.
If you want to test the library itself you can do more normal Ruby things.
| diff --git a/providers/instrument.rb b/providers/instrument.rb | |
| index 5197ef5..c7b96b6 100644 | |
| --- a/providers/instrument.rb | |
| +++ b/providers/instrument.rb | |
| @@ -17,10 +17,14 @@ | |
| # limitations under the License. | |
| # | |
| +def librato(email, token) | |
| + Librato::Metrics.new(email, token) | |
| +end | |
| + | |
| def load_current_resource | |
| email = new_resource.email || node.librato_metrics.email | |
| token = new_resource.token || node.librato_metrics.token | |
| - @librato = Librato::Metrics.new(email, token) | |
| + @librato = librato(email, token) | |
| @streams = if new_resource.metric | |
| [ | |
| { |
| require 'chefspec' | |
| require_relative 'provider_loader' | |
| describe 'instrument' do | |
| include ProviderLoader | |
| module MockLibrato | |
| attr_writer :librato | |
| def librato(*args) | |
| @librato | |
| end | |
| end | |
| let (:chef_run) { ChefSpec::ChefRunner.new.converge 'librato_metrics::default' } | |
| let(:instrument) do | |
| lwrp({ | |
| :resource_name => 'my_instrument', | |
| :cookbook_name => 'librato_metrics', | |
| :provider => 'instrument', | |
| :resource => 'instrument', | |
| :mixin => MockLibrato}).tap{|i| i.librato = double(Librato::Metrics)} | |
| end | |
| it "should be created if it doesn't exist" do | |
| streams = [{'metric' => 'foo', 'source' => '*', 'group_function' => 'sum'}] | |
| instrument.new_resource.streams(streams) | |
| instrument.load_current_resource | |
| instrument.librato.should_receive(:instrument_exists?).with('my_instrument').and_return(false) | |
| instrument.librato.should_receive(:create_instrument).with('my_instrument', streams) | |
| instrument.action_create | |
| end | |
| it "shouldn't be created if it does exist" do | |
| instrument.load_current_resource | |
| instrument.librato.should_receive(:instrument_exists?).with('my_instrument').and_return(true) | |
| instrument.librato.should_not_receive(:create_instrument) | |
| instrument.action_create | |
| end | |
| it "should use a metric if one is provided" do | |
| metric = {'metric' => 'foo', 'source' => '*', 'group_function' => 'average'} | |
| instrument.set_new_resource(metric) | |
| instrument.load_current_resource | |
| instrument.librato.should_receive(:instrument_exists?).with('my_instrument').and_return(false) | |
| instrument.librato.should_receive(:create_instrument).with('my_instrument', [metric]) | |
| instrument.action_create | |
| end | |
| end |
| module ProviderLoader | |
| def cookbook_files(type) | |
| chef_run.run_context.cookbook_collection.values.map do |c| | |
| c.send("#{type}_filenames".to_sym).map do |p| | |
| {:cookbook_name => c.metadata.name, :filename => p} | |
| end | |
| end.flatten | |
| end | |
| def filename_for(cookbook_name, type, name) | |
| cookbook_files(type).find do |p| | |
| p[:cookbook_name] == cookbook_name and | |
| Pathname.new(p[:filename]).basename.sub_ext('').to_s == name | |
| end[:filename] | |
| end | |
| def lwrp(options) | |
| provider_file = filename_for(options[:cookbook_name], :provider, options[:provider]) | |
| resource_file = filename_for(options[:cookbook_name], :resource, options[:resource]) | |
| clazz = Chef::Provider.build_from_file(options[:cookbook_name], provider_file, chef_run.run_context) | |
| resource_clazz = Chef::Resource.build_from_file(options[:cookbook_name], resource_file, chef_run.run_context) | |
| prov = clazz.new(resource_clazz.new(options[:resource_name], chef_run.run_context), chef_run.run_context) | |
| prov.extend(options[:mixin]) if options[:mixin] | |
| prov.extend(Module.new do | |
| def set_new_resource(atts) | |
| atts.each_pair{|key, value| new_resource.send(key, value)} | |
| end | |
| end) | |
| prov | |
| end | |
| end |