4

I am trying to test a provider in Chef using ChefSpec. In this provider, I am calling another external provider, which I would like to mock/disable, so that only my provider is being executed, not the external provider as well.

My provider is basically this:

action :deploy do
  app = new_resource.app
  deploy_data = new_resource.deploy_data

  opsworks_deploy do
    deploy_data deploy_data
    app app
  end

  Chef::Log.debug("This is where the actual code to test is located.")

end

I thought I can mock this somehow by using Chef::Provider::LWRPBase.build_from_file with an empty provider to supply the external provider mock. While there is apparently a Resource and Provider being generated, it apparently is not registered where it is supposed to be, since the test still complains about the external provider being missing.

Any ideas, hints or examples would be awesome - all examples for provider tests I found are using way simpler and selfcontaining providers, so they do not really help here.

If more context is needed, the provider in question is to be found here: https://github.com/fh/easybib-cookbooks/blob/0a9f7935371d6dc89796e83041cf5092bd96167a/easybib/providers/deploy.rb and the (crappy, nonworking, work in progress verision) of my test is here: https://github.com/fh/easybib-cookbooks/blob/0a9f7935371d6dc89796e83041cf5092bd96167a/easybib/spec/easybib_deploy_spec.rb

edit: Basically, the question here is not how to "overwrite" an existing Provider in my cookbooks with a stub, but how to programmatically create and provide a provider during a ChefSpec run, which does not exist in my cookbooks I am testing.

1 Answers1

0

You need to stub the created class:

let(:my_double) { double('opsworks_deploy') }
Chef::Resource::OpsworksDeploy.stub(:new).and_return(my_double)
sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • The problem here is in the Opsworks-Specific scenario, where you basically have two different cookbook repositories - your own and the opsworks supplied one. Since `opsworks_deploy` is in the opsworks one, this fails with 'uninitialized constant Chef::Resource::OpsworksDeploy'. When I am trying to stub one of the Resources in my own cookbook repository, this works perfect. Do you have a hint how to actually "create" `Chef::Resource::OpsworksDeploy`? I hoped that this is what LWRPBase.build_from_file does, but it apparently is not. – Florian Holzhauer Mar 20 '14 at 06:41
  • You would want to create a mock object in your spec_helper or a spec/library/helpers.rb that has the same name/type as the resource you are mocking and then have it return values for the specific methods you are trying to access. You can also override those values similar to how the example with the stub is showing. – dragon788 May 17 '18 at 22:02