I have a recipe to install components for IIS. Since there's a lot, it's an array that feeds into a windows_feature
install block. Like so:
strings.each do |st|
windows_feature st do
guard_interpreter :powershell_script
not_if "$ret = Get-WindowsOptionalFeature -Online -FeatureName #{st}; if ($ret.State -eq 'Disabled' ) { return 'false'} else {return 'true'}"
action :install
end
end
My associated Chefspec block has the same array contents feed into it. Block is such:
describe 'HEQIIS::IIS' do
let(:chef_run) { ChefSpec::SoloRunner.converge('HEQIIS::IIS') }
strings.each do |st|
it "installs_#{st}" do
stub_command("$ret = Get-WindowsOptionalFeature -Online -FeatureName #{st}; if ($ret.State -eq 'Disabled' ) { return 'false'} else {return 'true'}").and_return(false)
expect(chef_run).to install_windows_feature("#{st}")
end
end
end
When I run the Chefspec on the cookbook, I get the error:
HEQIIS::IIS installs_IIS-LegacyScripts
Failure/Error: let(:chef_run) { ChefSpec::SoloRunner.converge('HEQIIS::IIS') }
ChefSpec::Error::CommandNotStubbed:
Executing a real command is disabled. Unregistered command:
command("$ret = Get-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole; if ($ret.State -eq 'Disabled' ) { return 'false'} else {return 'true'}")
You can stub this command with:
stub_command("$ret = Get-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole; if ($ret.State -eq 'Disabled' ) { return 'false'} else {return 'true'}").and_return(...)
# ./heqiis/spec/default_spec.rb:70:in `block (2 levels) in <top (required)>'
# ./heqiis/spec/default_spec.rb:75:in `block (3 levels) in <top (required)>'
In the error, where it displays the -Featurename as 'WebServerRole', it does that for every line (30 entries). Indicating that it's only iterating over the first item at that stage. That, combined with the fact that I'm definitely using a stub_command block, I'm not really sure why it's erroring. Anyone have any thoughts?
In your spec, your chef run is being converged in the let block. Does moving your stub_command()
calls to be in a before do ... end
block help?
EDIT: indeed, your recipe file is setting up the whole array's worth of commands that need to be stubbed for each of the spec's expect() calls. Adding a second loop, inside a before block, for stubbing out all commands will solve your issue.