Reputation: 3425
We use the inspec framework a lot.
It encourages code such as the following, and we have a lot of it:
rock_critic/controls.rb
from https://docs.chef.io/inspec/inputs/#a-simple-example:
# Set a default value for an input. This is optional.
input('amplifier_max_volume', value: 10)
control 'Big Rock Show' do
describe input('amplifier_max_volume') do # This line reads the value of the input
it { should cmp 11 } # The UK'S LOUDEST BAND
end
end
input.yml
:
amplifier_max_volume: 11
This would be executed as:
inspec exec rock_critic --input-file input.yml
We would like to run this code with a variety of scenarios (e.g. list of pets from different sources, like files or created at runtime), using regular Ruby instead of the inspec
wrapper. i.e., ruby rock_critic/controls.rb
But if you do that, this is what you get:
$ ruby ./controls/controls.rb 12:14:45
./controls/controls.rb:2:in `<main>': undefined method `input' for main:Object (NoMethodError)
$
So, perhaps I got the title or vocabulary wrong, but
what's the best way to mock a method like input()
, which is defined globally (main:Object
)?
Ideally, we'd like to have a separate test (describe
, it
, etc.) and pass in a variety of inputs to input()
.
I've tried mixins and stuff like that, but it never quite works. Is there a good example? We're probably doing something wrong.
Hope that's a better explanation, thank you!
The hack I've been using is monkey-patching Object
.
require 'minitest/autorun'
input_hash = {
'amplifier_max_volume' => 12
}
Object.define_method(:input) { |key, **opts| input_hash[key] }
require_relative 'rock_critic/controls.rb'
Unfortunately, this doesn't seem quite right and it's not easy to supply different values for input()
.
Upvotes: 0
Views: 71
Reputation: 1
You're facing an issue because input()
is a method provided by the InSpec DSL and not a global function in Ruby.
when you try to run the code with Ruby directly, it's unable to recognize input()
. A possible workaround could be to define a mock method in the Kernel module or use the actual inspec
command to test the real behavior of your code.
Upvotes: -1