Is there a way I can use a custom fact while using rspec? My module works fine and the custom fact exists and works as intended when I do a puppet run on my agent, but when I try to use the same fact in rspec I get the following error:

Failure/Error: it { should contain_class('zabbixconfig') }

       Evaluation Error: Unknown variable: 'pskkey_generate'. at /etc/puppetlabs/code/environments/production/modules/zabbixconfig/spec/fixtures/modules/zabbixconfig/manifests/init.pp:46:13 on node puppet-master-poc

The pskkey_generate in the error above is my custom fact, and here's a snippet of my class including it:

$pskkey = $pskkey_generate

Does anyone know how to get rspec to recognize my custom fact? Any help would be appreciated.


In your spec/spec_helper.rb file you can add the following:

RSpec.configure do |c|
  c.default_facts = { :pskkey_generate => '...' }

See https://github.com/rodjek/rspec-puppet#default_facts

  • Thanks! I understand that the '...' needs to be replaced with the value of the pskkey_generate, but the pskkey_generate is a dynamically generated key. The command used to generate the key is openssl rand -hex 32. Since it's random, is there a way I can assign the value of the output to the pskkey_generate variable in the default_facts as well? If not I may just not unit test it for now and come back to it later. – AndreasKralj Feb 27 '19 at 13:49
  • Not really, as facts can behave differently on the host/OS that you're developing on versus the intended host/OS your code will run on. But by setting the fact to a known value, you can test that it affects your module in a known way. If the value just gets written out to a file, then you can add a test to check that with something like it { is_expected.to contain_file('/some/file').with_content('abc123') }, assuming you set the pskkey_generate fact to abc123 in your tests. – bodgit Feb 27 '19 at 14:06

In your case, it probably is best to hard code a known value of your fact in default_facts as bodgit suggests. In other cases, when the fact comes from a third party module, it is annoying to have to add mocking to make realistic tests of your use of their code.

I have added at the top of my spec/spec_helper.rb:

if ENV.include? 'MODULEPATH'
  top_path = File.dirname(File.dirname(__FILE__))
  ENV['FACTERLIB'] = ENV['MODULEPATH'].split(/:/).map do |p|
    p.start_with?('/') ? p : File.join(top_path, p)
  end.map do |p|
    Dir.glob(File.join(p, '*/lib/facter'))

When the Facter library loads, it will honour the FACTERLIB environment variable and evaluate all the custom facts supplied by the modules in your Puppet environment.

A typical value for MODULEPATH is "design:modules" when testing environments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.