Not able to stub library cookbook method #549

Closed
haad opened this Issue Jan 7, 2015 · 4 comments

Projects

None yet

2 participants

@haad
haad commented Jan 7, 2015

In my cookbook I'm using code like this

::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)
node.set['ssl_keystore_pass'] = secure_password

I would like to stub secure_password method in my spec files to make it work with my tests.

  before do
    allow_any_instance_of(Chef::Recipe).to receive(:secure_password).and_return('VerySecurePasswordForTest')
  end

  it 'should include required java/ark recipes' do
    expect(chef_run).to include_recipe('java::default')
    expect(chef_run).to include_recipe('ark::default')
  end

with these settings in place it still doesn't work and I'm getting same error

  1) rsdtomcat::default should include required java/ark recipes
     Failure/Error: end.converge(described_recipe)
     NoMethodError:
       undefined method `secure_password' for Opscode::OpenSSL::Password:Module
     # /var/folders/yq/_h9bmb6x1qxb7p4_w5xhkgx80000gn/T/d20150107-31232-9gzxp7/cookbooks/rsdtomcat/recipes/default.rb:30:in `block in from_file'
     # /var/folders/yq/_h9bmb6x1qxb7p4_w5xhkgx80000gn/T/d20150107-31232-9gzxp7/cookbooks/rsdtomcat/recipes/default.rb:24:in `from_file'
     # ./spec/unit/recipes/default.rb:8:in `block (2 levels) in <top (required)>'
     # ./spec/unit/recipes/default.rb:19:in `block (2 levels) in <top (required)>'
@sethvargo
Owner

@haad does this recipe actually converge? It looks like you have a bug in that module.

For Chef, I don't recommend every mixing a module into a recipe as I think it's horrible practice and makes things like this more difficult to test. Why not make Opscode::OpenSSL::Password a self-extending module or class?

module Opscode
  module OpenSSL
    class Password
      def self.secure_password
        # ...
      end
    end
  end
end

Then invoke it like Opscode::OpenSSL::Password.secure_password and stub it like allow(Opscode::OpenSSL::Password).to receive(:secure_password).

@sethvargo sethvargo closed this Jan 7, 2015
@haad
haad commented Jan 7, 2015

This would require that I would fork community openssl cookbook which is not what I want if it's not necessary. Is there any other way to get this working ?

@sethvargo
Owner

@haad blah omg that code is so horrible inefficient! (sorry I digress). Do this instead:

require "securerandom"
node.set['ssl_keystore_pass'] = SecureRandom.hex(20) # or SecureRandom.base64(20)

Then you can stub SecureRandom pretty easily:

allow(SecureRandom).to receive(:hex).and_return("whatever")

SecureRandom is also a far-better implementation (and more secure) than what is current in the OpenSSL cookbook.

@sethvargo
Owner

It bugged me so much that I even submitted a PR to make it better: chef-cookbooks/openssl#18

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment