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 |