Unit Testing nested node attributes

Hi!

I'm trying to refactor some unused attributes, but I'm stumped by stubbing nested attribute for example;

node['kernel']['machine']

I'm using this code to stub out a single level array:

before do
  allow(subject).to receive(:[]).with('platform_family').and_return(platform_family)
end

context 'with rhel family' do
  let(:platform_family) { 'rhel' }

  it 'returns the correct path' do
    expect(subject.apache_binary).to eq '/usr/sbin/httpd'
  end
end

Any pointers to being able to stub out nested node attributes would be great!

Thanks,
Dan

You don't generally stub node attributes, you make a real Node object and fill it in with the test data, and feed that to the rest of your code. ChefSpec automates most of that process :slight_smile:

1 Like

thanks for the reply :slight_smile:

I'm a little confused how to go about testing this when it's outside a recipe/resource right now.

I've haven't quite got as far as re-implementing recipe or resource tests for apache2 yet(!).

Here's the offending library https://github.com/sous-chefs/apache2/blob/helper-libexec_dir/libraries/helpers.rb#L61-L72

And how I'm stubbing out the node and attributes: https://github.com/sous-chefs/apache2/blob/helper-libexec_dir/spec/libraries/lib_dir_spec.rb#L6-L18

The only mention (that I'm seeing) of library testing in ChefSpec is here: https://github.com/chefspec/chefspec#ruby-code which is a little brief to go off :confused:

This is how I've tested libraries historically:

  1. Create a test cookbook inside your cookbook where you want to test libraries
  2. Update Berkshelf so it can resolve test cookbook
  3. Create a library test in which you use a default recipe from your test cookbook which should have NOTHING in it -- you're just simply using this as a mechanism for the ChefSpec::ServerRunner or ChefSpec::SoloRunner to compile the cookbooks, making available your library methods.
  4. Then just write normal unit tests.

Alternatively (depends on libraries), just create a simple spec (e.g. spec/unit/libraries/library_name_spec.rb) and inside that use require_relative '../../../../libraries/library_name' and continue writing normal unit tests. I hope this helps, if you want more just hit me up in the chefcommunity slack.

For anyone looking for reference, apache2, postgresql and haproxy now have a bunch of chefspec testing for custom resources

Example from HAProxy:

Apache2 resource testing:
https://github.com/sous-chefs/apache2/tree/install-resource/spec/resources
(if this link doesn't work in the future, it's probably because it's on master)

Apache2 library testing:
https://github.com/sous-chefs/apache2/tree/install-resource/spec/libraries
(if this link doesn't work in the future, it's probably because it's on master)